user8900498
user8900498

Reputation:

allocation with char pointer

I am beginner.I have a file which has lines like MONSTER,ERRTU,14,2 . when i tried to read the lines and store them into a dynamic memory allocated array. it seems like it worked at first but then when i tried to print the elements of it later , it doesnt work properly.Is it about using char * ? How can I fix this problem?

here my code is;

char *lines_ptr;
line_ptr=(char *)malloc(line*(sizeof(char)*100));   
int i=0;

if (fptr==NULL){

    printf("file could not be opened.");
}
else{ 

//line=number of lines
while(!feof(fptr)){
    for(i=0;i<line;i++){

        fscanf(fptr,"%s",lines_ptr+i);

        printf("%s\n",(lines_ptr+i));
    }
}

printf("%s",(lines_ptr));//this part shows me i did something wrong.

}  

here is my output;

   HERO,DRIZZT,8,3
   HERO,CATTIE,6,3
   HERO,BRUENOR,10,1
   HERO,WULFGAR,12,4
   MONSTER,TROLL,4,3
   MONSTER,GOBLIN,1,3
   MONSTER,UNDEAD,1,1
   MONSTER,VERMIN,3,2
   MONSTER,MINDFLAYER,10,2
   MONSTER,ERRTU,14,2
   HHHHMMMMMMONSTER,ERRTU,14,2 

why does it happen?

Upvotes: 0

Views: 79

Answers (4)

user3629249
user3629249

Reputation: 16540

the following proposed code:

  1. always reads the whole line from the file
  2. properly checks for errors
  3. properly places the read in data in the 'malloc'd array
  4. eliminates the clutter from the code
  5. eliminates the use of a 'magic' number in the code

and now the proposed code

    if ( !fptr )
    {
        perror( "file could not be opened." );
        exit( EXIT_FAILURE );
    }

    // implied else, fopen successful

    #define MAX_LINE_LEN 100

    //size_t line=number of lines
    char *line_ptr = malloc( line * MAX_LINE_LEN ));
    if( !line_ptr )
    {
        perror( "malloc failed" );
        exit( EXIT_FAILURE );
    }

    // implied else, malloc successful

    size_t i = 0;
    // Note: '%[^\n]' reads to end of line, but not the newline char
    //      AND appends a NUL byte to the end of the input
    //      '%*c' reads and discards the newline char
    // Note: using the '%*c' requires the last line in the file ends with a newline char
    //      otherwise the last call to `fscanf()` will 'hang' looking for the final newline
    while( i < lines && 1 == fscanf(fptr,"%[^\n]%*c", line_ptr+(MAX_LINE_LEN*i) ) )
    {
        printf( "%s\n", line_ptr+(MAX_LINE_LEN*i) );
        i++;
    }

Upvotes: 0

krpra
krpra

Reputation: 464

There are some mistakes you are doing.First look carefully what you are messing with in the picture.Suppose there are two line in the input hello and world,while taking the first input line_ptr starts from 0,so it will store hello from 0 to 4 but in second line line_ptr is incremented to 1 so it will store world from 1 to 5 and this will go on if more lines are there. enter image description here NOTE: Always check the return value of scanf() or fscanf()

For taking line as a input in c, you should use Array of pointers like char *lineptr[MAXLINE];

 int readline(char* lineptr[])
 {
      char line[1000];
      for(i=0;i<MAXLINE;i++){
           if(fscanf(stdin,"%s",line)){
              char *temp=malloc((strlen(line)+1)*sizeof(char));
              strcpy(temp,line);
              lineptr[i]=temp;  
           }
      }
      return i; 
 }

This function will read a line in a variable line, then it will allocate memory for that line in temp and lineptr[i] will point to that new line.It returns number of lines read.

Upvotes: 0

Tom&#39;s
Tom&#39;s

Reputation: 2506

you incorrectly use "line_ptr" (and so many other stuff ...).

From what I understand, it's seem you whant to load the entire file into "line_ptr", each file's line being in "line_ptr[i]".

If that so, then I advise you to take your time and do really simple code, and after, make it more complicated.

For instance, dont use malloc : with your current code, it's useless anyway.

Let's say you have a file with NB_LINE line at maximum, each line having NB_MAX_CHAR character at maximum.

#define NB_LINE_MAX 50
#define NB_CHAR_MAX 100

char   lines[NB_LINE_MAX][NB_CHAR_MAX];
size_t nbLines = 0;

for (nbLines = 0; fgets(lines[nbLines], NB_CHAR_MAX, fptr); ++nbLines) {
  // Nothing to do, fgets do it for us
}

if (!feof(fptr)) {
  // problem while reading :/
}


printf("Test :\");
for (size_t i = 0; i < nbLines; ++i) {
  printf("%d : %s", i, lines[i]);
}

Does this code work ? If yes, try to improove it by removing NB_LINE_MAX first (then you can have at many line you want in your file, not only 50) and after, try to remove NB_CHAR_MAX (then you can have a line without char limitation).

Misc remark :

  • sizeof(char) is alway 1, always. So you can delete it from your malloc.
  • fscanf(fptr,"%s",lines_ptr+i) is dangerous. %s will read at many char it want, so if he read 500 char but lines_ptr can only hold 100 of them, it will write somewhere not good, and you will probably have SIGSEV runtime crash.
  • while(!feof(fptr)) already say by another, but it's note how you use feof.

Upvotes: 0

sg7
sg7

Reputation: 6298

HHHHMMMMMMONSTER,ERRTU,14,2 //why does it happen?

What you do is as follows.

You read to the line buffer, but every time you move the beginning of the text by 1 character. So when you come back and print beginning of the buffer you will get all the first characters of all previously read lines plus last read line.

Upvotes: 3

Related Questions