Reputation: 26009
I just started programming in C a few days ago. My program opens a file, reads it line by line then removes stuff I don't need (brackets, newline,etc..), then once I just have the data in a comma separated format I want to add it to an array(then add that array to a array of arrays). I'm at the point where I am tokenize the comma separated string but I keep getting EXC_BAD_ACCESS, Could not access memory.
when I run it in debugger.
What am I doing wrong? Here's the section of my code that is giving me the problem:
//now data(variable: line) looks like this: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 4
char *str_ptr;
str_ptr = strtok(line, ",");
for(; str_ptr != NULL ;){
fprintf(stdout, "%s\n", str_ptr);
str_ptr = strtok(NULL, ",");
}
Here's my entire code:
#include <stdio.h>
int main() {
char line[1024];
FILE *fp = fopen("/Users/me/Desktop/output.txt","r");
printf("Starting.. \n");
if( fp == NULL ) {
return 1;
}
int count = 0;
int list[30]; //items will be stored here
while(fgets(line, 1024, fp) != EOF) {
count++;
//parse the text in the line Remove the open bracket, then remove the last newline,comma and close bracket
// data looks like this: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 4],
size_t len = strlen(line);
memmove(line, line+1, len-4);
line[len-4] = 0;
printf("%s \n",line);
//parse the numbers in the char
//now data looks like this: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 4
char *str_ptr;
str_ptr = strtok(line, ",");
for(; str_ptr != NULL ;){
fprintf(stdout, "%s\n", str_ptr);
str_ptr = strtok(NULL, ",");
}
//for testing just stop the file after two lines
if (count == 2) {
break;
}
if ( count > 1000000) {
printf("count is higher than 1,000,000 \n");
count = 0;
}
}
printf(" num of lines is %i \n", count);
return 0;
}
Other than the debugger I'm not sure how to get meaningful information in this case.
Sorry, didn't know how to do this. Here is a copy of the stack in the debugger (other than main, if I click on them they all say "No source available for .." then the items in the list:
Thread [1] (Suspended : Signal : EXC_BAD_ACCESS:Could not access memory)
strlen() at 0x7fff875ef4f0
__vfprintf() at 0x7fff875908c3
vfprintf_l() at 0x7fff8758f18e
fprintf() at 0x7fff87598d9a
main() at learningC.c:77 0x100000d5a
Upvotes: 0
Views: 251
Reputation: 9698
I don't see anything wrong if the input file is always valid. I tried to compile and run it on my Mac and it's working really fine. Maybe you can upload sample file somewhere so we can see what's going on exactly, because the code in memmove
part is too vulnerable for the invalid input (blank line or short line for example). I would suggest to change it to
char* data = line;
size_t len = strlen(line);
if (len > 3) {
line[len - 3] = '\0';
data++;
}
char *str_ptr;
str_ptr = strtok(data, ",");
for(; str_ptr != NULL ;){
fprintf(stdout, "%s\n", str_ptr);
str_ptr = strtok(NULL, ",");
}
My code is still far from perfect data validation, but at least it won't throw seg fault on blank line.
Upvotes: 1
Reputation: 44444
fgets
returns a NULL
on error or EOF. Check for that not for EOF
.
while(fgets(line, 1024, fp) != NULL){
Upvotes: 1