0

I am working with struct types. I take in a line from my own file that says "cerberus guards the river styx". When I try to print it out, only the letter 'c' prints. I don't know why this is happening.

#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef unsigned int uint;

struct wordType
{
    char word[80];
    uint count;
};

struct wordType words[10];

int main( void ) {
    FILE * inputFile;
    char * line = NULL;
    size_t len = 0;
    ssize_t read;
    uint index;
    inputFile = fopen( "input.txt", "r");

    if( inputFile == NULL )
    {
        printf( "Error: File could not be opened" );
        /*report failure*/
        return 1;
    }   

    index = 0;
    while( ( read = getline( &line, &len, inputFile ) ) != -1 )
    {
        printf( "%s\n", line );
        *words[index].word = *line;
        printf("line = %s\n", (words[index].word) );
    }

    free( line );
    return 0; 
}   
1
  • Hint for future troubleshooting: replace printf( "Error: File could not be opened" ); with perror("fopen"); but first read man perror of course. Commented Apr 28, 2013 at 20:28

2 Answers 2

2
*words[index].word = *line;

copies line[0] into words[index].word[0], so that's only one character. If you want to copy the entire line, you have to use

strcpy(words[index].word, line);

But you should verify that the line fits, i.e.

strlen(line) < 80

before that.

Sign up to request clarification or add additional context in comments.

6 Comments

Using strcpy on buffer of indeterminate size is not very good... strncat or snprintf to the rescue.
@hyde The size of the destination is known, so it is easy to check whether the source would be too long, like I said to do. snprintf is a good idea if one wants to copy the start anyway.
@DanielFischer I guess you added that last bit by editing right after submitting first time, and I missed an edit reload? 'cos I could swear the length check was not there when I started writing the comment... But no matter, I'm sure OP knows, if he should discard or cut short too long lines here.
@hyde Yes, I hit submit a bit too early. But looking at the time stamps, you must be one of the very few people here who type slower than I do ;)
@DanielFischer I actually started writing my own answer after starting the comment, but then discarded it and got back to just continuing with the comment.
|
0

Ok this an issue with how you are allocating the line object's memory. According to your code you set up a char*, however you never allocate any memory to it. That being said your char* will only be able to hold 1 character, or more accurate the number of characters to fill a standard char in whatever system you are using.

To fix this you will want to put a malloc() call into your code to allocate the length of the string to the char*.

line = (char *)malloc(SizeofString);

This code will give your line object the correct size to hold the entire string, instead of just one character. However you will probably want to use the following as your string size to ensure platform independence.

SizeofString = sizeof(char) * numberofCharactersinString;

Then use strcpy() to copy the contents of the line.

EDIT:: It appears what I wrote above is misleading due to the way that the GetLine() call functions. which does the malloc() call for you.

6 Comments

I was under the impression you should always allocate the memory due to the possibility of overwriting variables with the string.
getline takes care of the allocation. That's why it gets the address of the pointer.
getline will do the malloc for you in this case, read the man page I linked to if you want details. Btw, sizeof(char) is defined to be one in C standard, so not needed for platform independence (well, at least when using standards-compliant compilers). Also, char* initialized to NULL (or left uninitialized for that matter) will not be able to hold even one char, it's invalid pointer which can hold nothing and must not be dereferenced.
Interesting I thought that char* intitialized to Null would still be able to point to at least 1 character location once a pointer was supplied, or am I wrong? Also thanks for the link made that make way more sense to me and I am fixing my post now.
@Nomad101 Pointer points to some memory location, and that's it. The rest depends on what that memory location is, and if it isn't in a valid string/buffer/array/char, then there isn't any magical mechanism where it could still hold one character on top of what is really in that memory location. This is why pointers are considered low level and "dangerous": it's responsibility of the programmer to make sure pointer points to where it should, and to know what kind of memory area it is.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.