0

I have created a linked list, that holds the name of colours (Hungarian) read from a file. What my program is supposed to, is to compare the s string with the contents of the file. If it matches, print out the corresponding name from the file. But it won't do a damn thing.

What could be the issue?

File contents:

zold piros sarga lila rozsaszin tukiszkek fekete feher narancs okkersarga szintelen

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #define MAX 30

    int getl(char s[], int lim) /*ez a függvény kéri be a beolvasandó karakterláncot*/
    {
    int c,i;
    for(i = 0; i < lim && (c = getchar()) != '\n' && c!=EOF; i++)
      s[i] = c;
    s[i] = '\0'; // tömb lezárasa
    while(c != '\n' && c!=EOF)
      c=getchar(); // puffer ürítése
    return i; // visszateresi értek: string hossza
    }

    struct szinek {

        char szinek[MAX];
        struct szinek *kov;

    };


int main()
{
    FILE *fp;
    char s[MAX] = "zold";
    fp = fopen("/home/dumika/Desktop/szinek.txt", "r");
    if(!fp) return;

    struct szinek *llist, *head = NULL, *prev = NULL;

    while(fgets(s, MAX, fp)) {

        if(!(llist = (struct szinek*)malloc(sizeof(struct szinek)))) break;
        if(head) {
          prev->kov  = llist;
        } else {
          head = llist;
        }
        prev = llist;
        llist->kov = NULL;

        strcpy(llist->szinek, s);
    }

    llist = head;

    while(llist != NULL)
    {
        if(!strcmp(llist->szinek, s))
        {
            printf("%s", llist->szinek);
        }
        llist = llist->kov;
    }
}
chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
  • 2
    Be more specific. What exactly is "won't do a damn thing"? What is the part of the code that acts not as expected? – Martin Jun 06 '16 at 19:43
  • if(!strcmp(llist->szinek, s)) - this is responsible for the part that when they match, it should print. But it won't print anything. If I take out the '!', it says they match. – Gábor Micskó Jun 06 '16 at 19:45
  • 4
    `fgets` keeps any `newline` which you must remove, please read man page. – Weather Vane Jun 06 '16 at 19:46
  • These should be in the `else` block, no? `prev = llist; llist->kov = NULL;` – Fiddling Bits Jun 06 '16 at 19:47
  • You're not traversing the list correctly, most likely. – Fiddling Bits Jun 06 '16 at 19:48
  • And how do I remove the newline? – Gábor Micskó Jun 06 '16 at 20:00
  • @GáborMicskó See http://stackoverflow.com/questions/2693776/removing-trailing-newline-character-from-fgets-input – nos Jun 06 '16 at 20:11
  • `fgets` will try to read the entire line (and will fail if it's longer than the max you specified). That's probably why it's failing. You probably want to use something like `strtok` to take the words one at a time. – Tom Karzes Jun 06 '16 at 20:53
  • 1
    @TomKarzes `fgets()` does not fail if the line is too long -- it just doesn't read the whole line. – John Bollinger Jun 06 '16 at 20:56
  • @GáborMicskó the answer in that link provided by "nos" that earned a 100 bounty is my favourite method. `s [ strcspn(s, "\r\n") ] = 0;` No conditions, no failures, no prob! – Weather Vane Jun 06 '16 at 21:03
  • @John Of course I meant it would fail to read the entire line. I should have said "and will fail to do so" to make it clearer. The point is that this is OP's problem. OP wants tokens and is instead trying to read the entire line into a buffer that's too small to hold it. – Tom Karzes Jun 06 '16 at 21:04
  • @WeatherVane I would say `'\0'` should be used in that case. Although I don't know of any exceptions, I'm not sure that C guarantees that `'\0'` is necessarily equal to `0`. – Tom Karzes Jun 06 '16 at 21:09
  • 3
    @TomKarzes `'\0'` is 100% equivalent to `0`. They even have the same type (`int`). – melpomene Jun 06 '16 at 21:12
  • @melpomene You're probably right. I still think it's better style to use `'\0'` in the context of a string terminator. – Tom Karzes Jun 06 '16 at 21:17

1 Answers1

2

Your program works fine for me. I suspect a combination of two things is confusing you:

  1. You initialize buffer s with "zold", but you use that buffer to read in the lines of your file, thereby overwriting the initial contents. When you later scan the linked list, therefore, you are looking for the last string you read, not for "zold".

  2. If there is a newline after szintelen in the data file then the last line your program reads will be blank or empty. When your program prints the match, you might not recognize it as bona fide correct output.

You could verify that the program is successfully matching a string by adding some text to the output it emits in that case. For example:

        if(!strcmp(llist->szinek, s)) {
            printf("found '%s'\n", llist->szinek);
        }

You can test for a specific string by using a string literal in that comparison instead of s, or by creating a separate array for the comparison value. For example:

        if(!strcmp(llist->szinek, "zold")) {
            printf("found '%s'\n", llist->szinek);
        }

For the latter, do not neglect to follow advice in comments to remove trailing newlines included by fgets().

John Bollinger
  • 160,171
  • 8
  • 81
  • 157
  • 1
    @GáborMicskó the 'quote marks' around `'%s'` will show if there is an embedded `newline` which might otherwise escape notice without them. – Weather Vane Jun 06 '16 at 21:41