michithebest
michithebest

Reputation: 95

Read part of a file in C

I've spent some time searching the internet for an answer, but still didn't find any help. I'd like to read a .txt file and store the values in int width, int height and char message.

Update: Furthermore I'd like to make the program adaptable in case if the order of the values in read.txt is different.

read.txt

width 40
height 20
message "Hello"

main.c file

FILE *file_in = fopen("read.txt", "r");

int width;
int height;
char *message = malloc(sizeof(char)*255);

fscanf(file_in, "width %d", &width);
fscanf(file_in, "height %d", &height);
fscanf(file_in, "message %s", message);

printf("width %d\n", width);
printf("height %d\n", height);

fclose(file_in);
return 0;

output

width 0
height 0

I'm trying to get the correct output. What am I doing wrong? Thank you.

Upvotes: 1

Views: 2682

Answers (5)

LPs
LPs

Reputation: 16213

This code

fscanf(file_in, "width %d", &width);
fscanf(file_in, "height %d", &width);

should be

char temBuffer[32];

fscanf(file_in, "%s %d\n", tempBuffer, &width);
fscanf(file_in, "%s %d\n", tempBuffer, &height);

BTW to write to out.txt file you have to use fprintf

fprintf(file_out, "width %d\n", width);
fprintf(file_out, "height %d\n", height);

EDIT This is a way to check the string value e assign the int value to the right variable.

char temBuffer[32];
int tempInt;
fscanf(file_in, "%s %d\n", tempBuffer, &tempInt);

if (strcmp(tempBuffer, "width") == 0)
{
   width = tempInt;
}
else if (strcmp(tempBuffer, "height") == 0)
{
   height = tempInt;
}

EDIT 2 Very importand: you mallocated message string. You must call free, talking..

Upvotes: 2

vk239
vk239

Reputation: 1044

You will need to use your out file pointer using fprintf to write the contents to a file. The width and height values in your output file are 0 because you never wrote the values read from the input file. Change your code to look like below -

FILE *file_in = fopen("read.txt", "r");
FILE *file_out = fopen("out.txt", "w+");
char line[80]; // assuming 80 is max size of the line in file
int width;
int height;

char *temp1 = malloc(sizeof(char)*255);
char *temp2 = malloc(sizeof(char)*255);

while(fgets(line, 80, file_in) != NULL)
{
    if (sscanf(line, "%s %s", temp1, temp2) == 2)
    {
        if (strcmp(temp1, "width") == 0)
        {
            width = atoi(temp2);
        }
        if (strcmp(temp1, "height") == 0)
        {
            height = atoi(temp2);
        }
    }
}
fprintf(file_out, "%s %d\n", "width", width);
fprintf(file_out, "%s %d\n", "height", height);

free(temp1);
free(temp2);
fclose(file_in);
fclose(file_out);
return 0;

Upvotes: 0

chux
chux

Reputation: 153338

Code failed because fscanf(file_in, "height %d\n", &height); did not first consume the proceeding's line '\n' and code did not check the result of fscanf().

Instead use fgets() as answered by vk239.

If really want to stay with fscanf(), incorporate error handling, add a leading space before keywords to consume prior white-space, limit string input.

FILE *file_in = fopen("read.txt", "r");
if (file_in == NULL) Handle_Error();

int width;
int height;
char message[255];

if (fscanf(file_in, " width%d", &width) != 1) Handle_Error();
if (fscanf(file_in, " height%d", &height) != 1) Handle_Error();
if (fscanf(file_in, " message%254s", message != 1) Handle_Error();

printf("width %d\n", width);
printf("height %d\n", height);

fclose(file_in);
return 0;

Upvotes: 0

Barmar
Barmar

Reputation: 780724

First read the field name into a variable. Then use that to determine which variable to write the value into:

char field_name[20];

while(fscanf(file_in, "%s", field_name) == 1) {
    if (strcmp(field_name, "width") == 0) {
        fscanf(file_in, "%d\n", &width);
    } else if (strcmp(field_name, "height" == 0) {
        fscanf(file_in, "%d\n", &height);
    } else if (strcmp(field_name, "message") == 0) {
        fscanf(file_in, "%s\n", message);
    }
}

Upvotes: 3

Elvis Teixeira
Elvis Teixeira

Reputation: 614

You read width twice if you look carefully our code. additionally you should add the '\n', the new line character at the end of the fscanf format string. Also you are printing to the screen, if you want to write the output file use fprintf() and finally call free() to release the memory you allocated with malloc. Your code should look like:

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

int main()
{
   FILE *file_in = fopen("read.txt", "r");
   FILE *file_out = fopen("out.txt", "w+");

   int width;
   int height;
   char *message = malloc(sizeof(char)*255);

   fscanf(file_in, "width %d\n", &width);
   fscanf(file_in, "height %d\n", &height);
   fscanf(file_in, "message %s\n", message);

   fprintf(file_out, "width %d\n", width);
   fprintf(file_out, "height %d\n", height);

   fclose(file_in);
   fclose(file_out);
   free(message);
   return 0;
}

Upvotes: 0

Related Questions