I'm doing Zed Shaw's Learn C The Hard Way course. On exercise 11, in the extra-credit question #2, he askes:
Make these loops count backward by using i-- to start at argc and count down to 0. You may have to do some math to make the array indexes work right.
Use a while loop to copy the values from argv into states.
I try:
#include <stdio.h>
int main(int argc, const char *argv[]){
int i = argc - 1;
while(i >= 0){
printf("arg %d: %s\n", i, argv[i]);
i--;
}
char *states[] = {
"California", "Oregon",
"Washington", "Texas"
};
int num_states = 4;
i = num_states - 1;
while( i >= 0){
printf( "state %d, %s\n", i, states[i]);
i--;
}
i = 0;
while(i < argc && i < num_states){
int j = 0;
while( (states[i][j++] = argv[i][j++]) != '\0' ){
i++;
}
states[i][j] = '\0';
}
i = num_states - 1;
while( i >= 0){
printf( "state %d, %s\n", i, states[i]);
i--;
}
return 0;
}
I get a Segmentation Fault
. I understand that you can't copy arrays in C, that they are const pointer or something similar (or so I read). That's why I try to copy character by character:
while(i < argc && i < num_states){
int j = 0;
while( (states[i][j++] = argv[i][j++]) != '\0' ){
i++;
}
states[i][j] = '\0';
}
Yet it doesn't work. How should I do this? The compiler gives me this warning when I compile:
$ make ex11
cc -Wall -g ex11.c -o ex11
ex11.c: In function ‘main’:
ex11.c:26:28: warning: operation on ‘j’ may be undefined [-Wsequence-point]
I don't get why it says that j
is undefined. valgrind
says this:
$ valgrind ./ex11 this is a test
==4539== Memcheck, a memory error detector
==4539== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al.
==4539== Using Valgrind-3.8.0 and LibVEX; rerun with -h for copyright info
==4539== Command: ./ex12 this is a test
==4539==
arg 4: test
arg 3: a
arg 2: is
arg 1: this
arg 0: ./ex11
state 3, Texas
state 2, Washington
state 1, Oregon
state 0, California
==4539==
==4539== Process terminating with default action of signal 11 (SIGSEGV)
==4539== Bad permissions for mapped region at address 0x400720
==4539== at 0x4005F1: main (ex11.c:26)
==4539==
==4539== HEAP SUMMARY:
==4539== in use at exit: 0 bytes in 0 blocks
==4539== total heap usage: 0 allocs, 0 frees, 0 bytes allocated
==4539==
==4539== All heap blocks were freed -- no leaks are possible
==4539==
==4539== For counts of detected and suppressed errors, rerun with: -v
==4539== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 2 from 2)
Segmentation fault
[EDIT 1] A switched my code for this
int i = 0;
while( i < argc && i < num_states ){
states[i] = argv[i];
i++;
}
It does work, but the compiler gives me a warning. Also, I realized after posting this question that my previous:
while( (states[i][j++] = argv[i][j++]) != '\0' ){
i++;
}
Is just plain wrong. Because the j++
is executed twice per loop, and that i++
should be outside that loop in the outer loop. And also as mentioned in the comment below, that the byte-by-byte copy that I try to do using array of arrays doesn't work because I actually have array of pointers.
That said, is there a way I could do this without having the compiler's warning?
j
is undefined because you have twoj++
es and it's not defined which ofstates[i][j++]
andargv[i][j++]
gets the lower and higher value ofj
. – icktoofay Aug 20 '12 at 3:00memcpy
would suffice. – R.. Aug 20 '12 at 3:10