-1

I have to find out how many times each character repeats in a linked list of strings. The string is stored and read from a file. I have to print out the result in 2 ways: alphabetic order and in growing order.

I have tried to write a function which will count the number of times a given char repeats, but it crashes.

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


struct list {
    char *string;
    struct list *next;
};

typedef struct list LIST;

int count(struct list* head, char search) // funct to calculate how many 
                                          //times 1 string appears
{
    struct list* current = head;
    int count=0;
    while (current!=NULL)
    {
        if(current->string == search)
            count++;
    }
    return count;
}

int main(void) {
    FILE *fp;
    char line[128];
    LIST *current, *head;

    head = current = NULL;
    fp = fopen("test.txt", "r");

    while(fgets(line, sizeof(line), fp)){
        LIST *node = malloc(sizeof(LIST));
        node->string = strdup(line);
        node->next =NULL;

        if(head == NULL){
            current = head = node;
        } else {
            current = current->next = node;
        }
    }
    fclose(fp);
    //test print
    for(current = head; current ; current=current->next){
        printf("%s", current->string);
    }

    count(head, "a");

    return 0;
}

The test.txt file contains:

Astazi nu este maine
John Kugelman
  • 349,597
  • 67
  • 533
  • 578
Vlad
  • 91
  • 7
  • I've added a line after the count++ in the `int count` function which is `current = current->next;` but when printing it out, it prints me 0, although it should be 2 – Vlad Mar 27 '21 at 08:19
  • Your example relies on a test.txt which you did not share with us. I suggest you simplify your example and hard-code the test data to demonstrate the problem. – Allan Wind Mar 27 '21 at 08:21
  • @AllanWind just edited the description, I've put the data from test.txt in it – Vlad Mar 27 '21 at 08:21
  • 1
    See [this C reference](https://en.cppreference.com/w/c). Compile your C code with [GCC](http://gcc.gnu.org) invoked as `gcc -Wall -Wextra -g`, improve your code to get no warnings, then use the [GDB](https://www.gnu.org/software/gdb/) debugger to understand the behavior of your executable. – Basile Starynkevitch Mar 27 '21 at 08:22
  • Take inspiration from the source code of existing open source programs like [GNU binutils](https://www.gnu.org/software/binutils/) or [GNU make](https://www.gnu.org/software/make/) – Basile Starynkevitch Mar 27 '21 at 08:23
  • You can also use, if allowed, the [Clang static analyzer](https://clang-analyzer.llvm.org/), or [Frama-C](http://frama-c.com/), or [Bismon](http://github.com/bstarynk/bismon). You could email me (in English or Russian) to `basile@starynkevitch.net` or in English only to `basile.starynkevitch@cea.fr` for questions about Frama-C or Bismon – Basile Starynkevitch Mar 27 '21 at 08:26
  • 1
    The problem here is that your code **emits several warnings** from the compiler but you don't mention it in the question. You should **google** those warning messages and read the relevant Stack Overflow questions **even before** posting your own question. – Antti Haapala -- Слава Україні Mar 27 '21 at 08:26
  • If there is a single node with string = "aa" should count() return 0, 1 or 2? – Allan Wind Mar 27 '21 at 08:34

1 Answers1

1

The problem is that if(current->string == search) compares a pointer (char *) to a char. If current->string is a single character you can use if(*current->string == search). If string contains multiple characters you have to tell me what the count() of the string "aa" is with search of 'a'. The other major problem is that your while loop in count() doesn't walk the linked list so it would result in an infinite loop.

int count(struct list *head, char search) {
    int count = 0;
    for(struct list* current = head; current; current = current->next) {
        for(int i = 0; current->string[i]; i++)
            if(current->string[i] == search) count++;
    }
    return count;
}
Allan Wind
  • 23,068
  • 5
  • 28
  • 38