-2

Strings are driving me crazy. It's like no buit-in function is useful.

What I want to do is this. I've got this file f:

1
I like fries
2
Do you like fries?
3
I like trains. 

How can I read the ENTIRE sentence "I like fries" from a file? So far nothing has worked for me. I do not know how long the sentence is and the variable I am reading / saving the sentence into is char *Blaa;

ok EDIT cause this is driving me crazy

I've got this

     typedef struct Student
{
int nrcrt;
char *name;
} Student;
Student *S;

  void Readstuff()
{
FILE *f;
int i;
f = fopen("students.txt","r");
if (!f)
{
    perror("can't open file.\n"); exit(EXIT_FAILURE);
}
char line[4096];
for(i=0;i<N;i++)
{

   fscanf(f,"%d",&S[i].nrcrt);
   printf("%d\n",S[i].nrcrt);
   while (fgets(line,sizeof(line),f) != 0)
    {
       strcpy(S[i].name,line);
    }
}
close(f);
}

I can read ints into S[i].nrcrt, but if I want to read a string an put it in a S[i].name, the entire universe explodes. I keep getting segmentation fault. I tried to read a line in a variable line and then copy it into S[i].name but nothing.

Let's pretend for the sake of argument a student's name can be "I like fries". I didn't want to overcomplicate the question so this is why I didn't actually say what I needed.

Ssurge
  • 29
  • 1
  • 5
  • 1
    possible duplicate of [C read file line by line](http://stackoverflow.com/questions/3501338/c-read-file-line-by-line) – Ken White May 09 '14 at 01:38
  • @KenWhite, while the problem is the same in that question, the issue at hand is not. It's not a duplicate of that – The Archetypal Paul May 09 '14 at 19:32
  • @Paul: See the revision history. At the time I voted to close, it was appropriate. As it is, it's actually still appropriate - the question is still about reading a line from a file. The error that is causing the segfault is a different topic entirely that did not exist in the original question. If a totally new question is now being asked, it belongs in a totally new post. – Ken White May 09 '14 at 19:36
  • @KenWhite, not entirely sure I agree, but for sure it was more likely to be appropriate... – The Archetypal Paul May 09 '14 at 20:00

1 Answers1

0

Addressing amended question

You have:

typedef struct Student
{
    int nrcrt;
    char *name;
} Student;
Student *S;

You don't show any code that is allocating either the array of Student structures or the space to store the name. In C, you always have to ensure that pointers have something to point to — and with the data structures you've shown, you'll need to manage a dynamic array of Students, and for each Student, you'll have to dynamically allocate their name. With dynamic memory management, you also have to ensure you release the allocated memory.

The simplest way to allocate the names is using the POSIX function strdup():

S[i].name = strdup(line);

You can find endless other questions on SO about managing dynamic arrays of structures in C. Or you could side-step the problem altogether by using:

Student S[MAX_STUDENTS];

Unless you have a reason to do dynamic memory allocation for the array, use that. If you change your structure, you can avoid strdup() there, too:

typedef struct Student
{
    int  nrcrt;
    char name[MAX_NAME_LEN];
} Student;

Original answer

There are various options. You show sentences on a single line; that's easy. Can the sentences spread over multiple lines of text?

It sounds like one of your problems is that you've not made your Blaa point to any data yet.

You can probably use fgets():

char line[4096];

while (fgets(line, sizeof(line), stdin) != 0)
{
    …process line (sentence)…
}

If you need to handle multi-line sentences, then you need to be prepared to build up the sentence from multiple lines. Do you have an upper bound on the length of a sentence? It is unlikely that you'll find many sentences that use more than 4 KiB of data, so you might simply read successive lines of the sentence into the single line buffer.

char line[4096];

char *buffer = line;
size_t buflen = sizeof(line);

while (fgets(buffer, buflen, stdin) != 0)
{
    if (isdigit((unsigned char)buffer[0]))
    {
        *buffer = '\0';
        …process sentence in line…
        buffer = line;
        buflen = sizeof(line);
    }
    else
    {
        size_t newline = strlen(buffer);
        buffer += newline;
        buflen -= newline;
    }
}
if (buffer != line)
{
    …process sentence in line…
}

If you can't place a reasonable upper bound on the sentence size, then you will have to build up the sentence piecemeal, reading lines into line and then copying that into a dynamically growing array (created using malloc() and realloc(), and eventually released by free()).

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
  • No sentence can spread over multiple lines. It is one line only. I've got a `Student[i].name` where I have to put in the name. So theoretically, I would go `for(i=0 – Ssurge May 09 '14 at 11:19
  • How do student names relate to sentences? Reading from a file instead of standard input is simply a question of changing `stdin` to the name of the file pointer you opened: `FILE *fp = fopen(argv[1], "r"); if (fp == 0) { …oops; failed to open file… }` and then using `fp` in the call to `fgets()`. Generally speaking, you've not told us the whole story of what you need, which makes it hard to guess what you want. You'll need to clarify your question to get it reopened. You should look at other questions and answers such as the proposed duplicate; they probably deal with your problems. – Jonathan Leffler May 09 '14 at 14:57
  • A short sentence or a name is the same thing. I like apples or "John Mark Thompson Newwhatever" I thought that reading a one line sentence is the same thing as reading a one line name. Which it is. – Ssurge May 09 '14 at 18:40
  • @Ssurge: Hmmm...OK, if that's what you mean, then you can be [Humpty Dumpty](http://www.goodreads.com/quotes/12608-when-i-use-a-word-humpty-dumpty-said-in-rather) for the day. In the rest of the English-speaking world, there is a vast difference between a name and a short sentence. And your original post didn't mention 'short' for the sentences. – Jonathan Leffler May 09 '14 at 18:43
  • I've edited my question. What difference does it make though reading 'I like fries' or 'Name1 Name2 Lastname'? – Ssurge May 09 '14 at 18:54
  • Not much beyond understanding what the hell you're up to. If you give misleading requirements, you get (unintentionally) misleading answers. – Jonathan Leffler May 09 '14 at 19:05
  • Ok, sorry about the confusion. The thing is, I do not know how many students there are or how long their name is going to be and this is why I had to allocate dynamically `Student *S` and the name `char *name` – Ssurge May 09 '14 at 19:18