1

I am novice to C langugage, so please bear with me. I've tried to read a file which contains strings but output obtained is single character.

#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>

#define CALLOC(num, type) ((char*)calloc (num, sizeof(char)))
#define FREE(addr) (free((void*) (addr)))

int i, count;
char *x, *y, *z;

int main (void) 

{

FILE *stream;
if ( (stream = fopen ( "test.txt", "r" )) == NULL )
{ printf ("Cannot read the new file\n");
exit (1);
}

count = 3;

x=CALLOC(count, char);
y=CALLOC(count, char);
z=CALLOC(count, char);


for ( i=0; i<count; i++ ) 
{ fscanf (stream,"%c %c %c", &x[i], &y[i], &z[i]);
printf ("\n %d %c %c %c ", i, x[i], y[i], z[i]);
}

FREE(x);
FREE(y);
FREE(z);

fclose (stream);

}

Input test.txt file contains

1 ab 1
2 aa 5
1 cc 1

current output

 0 1 a b
 1   1 2
 2   a a 

Expected output

 0 1 ab 1
 1 2 aa 5
 2 1 cc 1

I doubt whether I should use a character array but it seems not working and I feel reading a int using char is acceptable. Here I require the expected output, for this any method/suggestion is appreciated.

Richard Dally
  • 1,432
  • 2
  • 21
  • 38
Emman
  • 1,180
  • 1
  • 22
  • 38
  • 2
    really shouldnt be casting the pointer to free ( its pointless ). also no need to cast the calloc. and should move the global variables into main ( theres no need for them to be global ) – amdixon Jul 21 '15 at 10:41
  • [Do not cast the result of `malloc` in C](http://stackoverflow.com/q/605845/995714) – phuclv Jul 21 '15 at 11:34

3 Answers3

3

%c reads in only one char. So it's not going to read ab as a single char. Your lines in file and your formats don't correctly to read an entire line.

A simple approach is to use fgets() and print the entire line:

char line[256];
i = 0;

while(fgets(line, sizeof line, stream))
{
   printf ("%d %s", i, line);
   i++;
}

By the way, macros for calloc and free are unnecessary. They really don't make the code any easier to read than directly using those functions.

And the casts in them are also unnecessary.

P.P
  • 117,907
  • 20
  • 175
  • 238
  • It is printing as expected but it no more stores the values in any variable (such as x,y or z) that I can access later, I am trying to access only the second column ie "ab, aa, cc" is there any way to obtain? – Emman Jul 21 '15 at 10:50
  • If you need to look at values, then use `sscanf()` on `line`. But you have to use `%s` read strings such as `ab` and ensure the buffer you have can store as many bytes. – P.P Jul 21 '15 at 11:00
  • It's not only unneccessary but also not recommended http://stackoverflow.com/q/605845/995714 I've never seen any one uses `free` with cast – phuclv Jul 21 '15 at 11:36
  • @LưuVĩnhPhúc I have seen it before. But I don't recommend it in my answers/comments due to its exaggeration, authoritative-sounding and inflammatory nature. Instead I would always link to comp.lang.c (linked in the answer) page which explains quite clearly about the effects of casting without missing any necessary detail. Casting free is a pre-standard artifact where free used to take a `char*`. I have seen it old code. Still some (incorrectly) do it out of habit. – P.P Jul 21 '15 at 12:15
  • @BlueMoon as per the inputs I have removed the unnecessary casting and free. Since I am coding for a bigger puzzle I have used global variables so that I can access as and when required now I've used "sscanf(buffer, "%d%s%d", &line, hex, &ch);" and found working thanks. – Emman Jul 21 '15 at 12:30
0

The problem is you have the scan file. %c read a 8bit value. You scanned 3 char, but the file is contain 4 characters. If you don't use to be the value of the x, y, z I don't understand why use malloc.

Here a working source:

#include <stdio.h>
#include <stdlib.h>

int main() {
  int count,i;
  char w,x,y,z;
  FILE *stream;
  if((stream = fopen("test.txt","r")) == NULL) {
    printf("Cannot read the new file\n");
    return 1;
  }
  count = 3;
  for(i=0;i<count;++i) {
    fscanf(stream,"%c %c%c %c\n",&w,&x,&y,&z);
    printf("%d %c %c%c %c\n",i,w,x,y,z);
  }
  return 0;
}
0
for ( i=0;i<count; i++ ) 
        { 
            fscanf (stream,"%s %s %s", x, y, z);
            printf ("\n %d %s %s %s ", i, x, y, z);  
        }

You can modify your loop to this.This loop will read file until end of file and you have to use %s as ab is a string not charater so it can't be stored in a char variable.

ameyCU
  • 16,489
  • 2
  • 26
  • 41