2

I've used strcmp before and it worked as expected, but it's not working for me in my current code.

I'm reading a .csv file with the names of a bunch of famous people. "Mark Zuckerberg" is the key name that triggers things that my code will eventually do (once I get past this bump in the road and this has nothing to do with what he's been in the news for lately). I'm using a counter (queue_size) to count the number of lines in the .csv file. My goal is to save the value of the counter when strcmp(temp_name, key) == 0 but I'm not entering that if statement and I can't see why.

The key appears in the .csv file as "Mark,Zuckerberg". I've tried using strtok to eliminate the comma. I was successful in doing that but strcmp() still isn't working (I adjusted the key to be "MarkZuckerberg"). I also added memset to clean the slate with each iteration but that didn't resolve the issue either.

Commenting the line, temp_name[strlen(temp_name) - 1] = '\0'; doesn't appear to change anything either. I know that my struct is getting all of the names because printf (I've since deleted) and my print_list function prints as expected.

I really need help finding out why I'm not entering that if statement.
Thanks in advance for any help that anyone can provide.

I think that it's something dumb that I'm overlooking but I just can't find it.

Here's my code:

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

typedef struct char_node {
    char name[40];
    struct char_node *next;
} char_node;

typedef struct char_queue {
    char_node *q_head;
    char_node *q_tail;
    int q_size;
} char_queue;

void enqueue(char_queue *q_ptr, char new_name[40]);
//int dequeue(char_queue *q_ptr);
void print_list(char_queue *queue);

int main() {
    int queue_size = 0;
    int m_z_position;
    char_queue queue;
    char temp_name[40];
    char key[] = "Mark,Zuckerberg";

    queue.q_head = NULL;
    queue.q_tail = NULL;
    queue.q_size = 0;

    FILE *file_input;
    file_input = fopen("party.csv", "r");

    memset(temp_name, '\0', sizeof(temp_name));

    while(fgets(temp_name, sizeof(temp_name), file_input)) {
        temp_name[strlen(temp_name) - 1] = '\0';
        if(strcmp(temp_name, key) == 0) {
            printf("test\n");
            m_z_position = queue_size;
        }
        enqueue(&queue, temp_name);
        memset(temp_name, '\0', sizeof(temp_name));
        queue_size++;
    }
    fclose(file_input);

//print_list(&queue);
    printf("m_z_position = %d\n", m_z_position);
    return 0;
}

void enqueue(char_queue *q_ptr, char new_name[40]) {
    char_node *new_node = (char_node*)malloc(sizeof(char_node));
    strcpy(new_node->name, new_name);
    new_node->next = NULL;
    int num;

    if(q_ptr->q_size == 0) {
        q_ptr->q_tail = new_node;
        q_ptr->q_head = new_node;
    } else {
        q_ptr->q_tail->next = new_node;
        q_ptr->q_tail = new_node;
    }
    (q_ptr->q_size)++;
    return;
}

void print_list(char_queue *queue) {
    char_node *temp_list;

    if(queue->q_head != NULL) {
        temp_list = queue->q_head;
        while(temp_list != NULL) {
            printf("%s\n", temp_list->name);
            temp_list = temp_list->next;
        }
    }
    printf("\n");
    return;
}

I can't figure out how to add the file but here are the contents of the .csv file

Jeff,Bezo
Bill,Gates
Warren,Buffett
Berkshire,Hathaway
Bernard,Arnault
Amancio,Ortega
Carlos,Slim
Charles,Koch
David,Koch
Larry,Ellison
Michael,Bloomberg
Larry,Page
Sergey,Brin
Jim,Walton
S,Robson
Alice,Walton
Ma,Huateng
Francoise,Bettencourt
Mukesh,Ambani
Jack,Ma
Sheldon,Adelson
Steve,Ballmer
Li,Ka-shing
Hui,Ka
Lee,Shau
Wang,Jianlin
Beate,Heister
Phil,Knight
Jorge,Paulo
Francois,Pinault
Georg,Schaeffler
Susanne,Klatten
David,Thomson
Jacqueline,Mars
John,Mars
Joseph,Safra
Giovanni,Ferrero
Dietrich,Mateschitz
Michael,Dell
Masayoshi,Son
Serge,Dassault
Stefan,Quandt
Yang,Huiyan
Paul,Allen
Leonardo,Del
Dieter,Schwarz
Thomas,Peterffy
Theo,Albrecht
Len,Blavatnik
He,Xiangjian
Lui,Che
James,Simons
Henry,Sy
Elon,Musk
Hinduja,family
Tadashi,Yanai
Vladimir,Lisin
Laurene,Powell
Azim,Premji
Alexey,Mordashov
Lee,Kun-Hee
Lakshmi,Mittal
Wang,Wei
Leonid,Mikhelson
Charoen,Sirivadhanabhakdi
Pallonji,Mistry
Ray,Dalio
Takemitsu,Takizaki
William,Ding
R,Budi
Gina,Rinehart
German,Larrea
Carl,Icahn
Stefan,Persson
Michael,Hartono
Joseph,Lau
Thomas,A
Vagit,Alekperov
James,Ratcliffe
Donald,Bren
Iris,Fontbona
Gennady,Timchenko
Abigail,Johnson
Vladimir,Potanin
Lukas,Walton
Charlene,de
Zhang,Zhidong
Petr,Kellner
Andrey,Melnichenko
David,A
Klaus-Michael,Kuehne
Li,Shufu
Mikhail,Fridman
Rupert,Murdoch
Dhanin,Chearavanont
Robert,Kuok
Emmanuel,Besnier
Shiv,Nadar
Viktor,Vekselberg
Aliko,Dangote
Harold,Hamm
Steve,Cohen
Dustin,Moskovitz
Marcel,Herrmann
Reinhold,Wuerth
Charles,Ergen
Eric,Schmidt
Philip,Anschutz
Jim,Kennedy
Blair,Parry-Okeden
Alain,Wertheimer
Gerard,Wertheimer
Leonard,Lauder
Heinz,Hermann
Dilip,Shanghvi
Hasso,Plattner
Stephen,Schwarzman
Lei,Jun
Hans,Rausing
Alisher,Usmanov
Donald,Newhouse
Peter,Woo
Luis,Carlos
Robin,Li
Carlos,Alberto
Seo,Jung-Jin
Kumar,Birla
Alexander,Otto
Stefano,Pessina
Udo,A
Wang,Wenyin
Andrew,Beal
Lee,Man
John,Menard
Xu,Shihui
Zhou,Hongyi
Gong,Hongjia
Michael,Otto
David,Tepper
Roman,Abramovich
Liu,Qiangdong
Robert,A
Alberto,Bailleres
Uday,Kotak
Pierre,Omidyar
Walter,PJ
Dietmar,Hopp
Graeme,Hart
Eduardo,Saverin
Yan,Zhi
Radhakishan,Damani
German,Khan
Ronald,Perelman
Gautam,Adani
Micky,Arison
Pan,Zhengmin
Joseph,Tsai
Thomas,Frist
Mikhail,Prokhorov
Galen,Weston
Zong,Qinghou
Eyal,Ofer
Charles,Schwab
Gianluigi,A
Herbert,Kohler
Viktor,Rashnikov
Harry,Triguboff
August,von
Yao,Zhenhua
Jan,Koum
Cyrus,Poonawalla
James,Goodnight
Ken,Griffin
Giorgio,Armani
Ernesto,Bertarelli
Savitri,Jindal
Sunil,Mittal
James,Chambers
Katharine,Rayner
Margaretta,Taylor
Terry,Gou
Gordon,Moore
James,Irving
Stanley,Kroenke
Melker,Schorling
Johann,Graf
Guo,Guangchang
John,Malone
Xavier,Niel
Silvio,Berlusconi
Carl,Cook
David,Geffen
Hui,Wing
Walter,Kwok
George,Soros
Edward,Johnson
Massimiliana,Landini
David,Duffield
George,Kaiser
Patrick,Soon-Shiong
Zhou,Qunfei
Nicky,Oppenheimer
Sun,Piaoyang
Wu,Yajun
Alexei,Kuzmichev
Stephen,Ross
Vincent,Bollore
Pauline,MacMillan
Jay,Y
Anders,Holch
Eli,Broad
Michael,Kadoorie
Iskander,Makhmudov
Frederik,Paulsen
Sun,Hongbin
Christy,Walton
Shahid,Khan
Ananda,Krishnan
Carrie,Perrodo
Quek,Leng
Wang,Wenxue
John,Doerr
Patrick,Drahi
Eva,Gonda
Willi,A
Ricardo,Salinas
Suh,Kyung-Bae
Pollyanna,Chu
John,Fredriksen
Goh,Cheng
Sri,Prakash
Lu,Zhiqiang
Jorn,Rausing
Johann,Rupert
Jacques,Saade
Wu,Shaoxun
Leonid,Fedun
Kim,Jung-Ju
Sandra,Ortega
Jim,Pattison
Michael,Platt
Chan,Laiwa
David,Green
Hank,A
Dmitry,Rybolovlev
Tsai,Eng-Meng
Andreas,von
Oleg,Deripaska
Liu,Yongxing
Ludwig,Merckle
Brian,Acton
John,Grayken
Ann,Walton
Augusto,A
Finn,Rausing
Mark,Zuckerberg
Kirsten,Rausing
Odd,Reitan
Nassef,Sawiris
Wee,Cho
Aloys,Wobben
Leon,Black
Ivan,Glasenberg
John,Paulson
Wei,Jianjun
Francis,Choi
Erivan,Haub
Jason,Jiang
Suleiman,Kerimov
Ian,A
Pang,Kang
David,Shaw
Kushal,Pal
John,A
Acharya,Balkrishna
Guenther,Fielmann
Daniel,Gilbert
Antonia,Johnson
Vikram,Lal
Akira,Mori
Maria-Elisabeth,Schaeffler-Thumann
Albert,Frere
Richard,Kinder
Robert,Kraft
Ralph,Lauren
Bruno,Schroder
Nusli,Wadia
Pierre,Bellon
Les,Wexner
Benu,Gopal
David,Cheriton
Ma,Jianrong
Whitney,MacMillan
Dan,Olsson
Vivek,Chaand
Teh,Hong
Abdulla,bin
Maria,Asuncion
Ralph,Dommermuth
Frank,Lowy
Wolfgang,Marguerre
Marijke,Mars
Pamela,Mars
Valerie,Mars
Victoria,Mars
David,A
John,Gokongwei
Kwon,Hyuk-Bin
Nancy,Walton
Lin,Yu-Ling
Tom,A
Robert,Rowling
Dennis,Washington
Yao,Liangsong
Zhang,Jindong
Juan,Francisco
David,Sun
John,Tu
Martin,Viessmann
Stef,Wertheimer
Hansjoerg,Wyss
James,Dyson
Laurence,Graff
Jen-Hsun,Huang
Charles,Johnson
Jerry,Jones
Kei,Hoi
Kwee,family
Lee,Shin
Richard,LeFrak
Shigenobu,Nagamori
Steven,Rales
Friede,Springer
Yeung,Kin-man
Rinat,Akhmetov
Shari,Arison
Dannine,Avara
Rahel,Blocher
Andrew,Currie
Scott,Duncan
Milane,Frantz
Diane,Hendricks
Magdalena,Martullo-Blocher
Hiroshi,Mikitani
Gabe,Newell
Pan,Sutong
Anthony,Pratt
John,Reece
Randa,Williams
Zhang,Bangxin
Stargateur
  • 24,473
  • 8
  • 65
  • 91
Brian.H
  • 73
  • 1
  • 7
  • Can you update the contents of your file? Did you try to verify the length of the string that you're reading from file? And, by any chance, is it case insensitive comparison? – Azeem Apr 14 '18 at 03:10
  • 1
    Another important thing is that `fgets` reads the newline character also, did you try to eliminate that? You can add `\n` at the end of your key and then give it a shot. – Azeem Apr 14 '18 at 03:12
  • See: [std::fgets][http://en.cppreference.com/w/cpp/io/c/fgets] – Azeem Apr 14 '18 at 03:13
  • @Azeem OP did eleiminate `\n` by `temp_name[strlen(temp_name) - 1] = '\0';` immediately after `fgets()` – Achal Apr 14 '18 at 03:22
  • @achal: You are right! The newline is eliminated. Then, there might be extra space(s) in the file. OR he might need case insensitive comparison. It's just a guess. Without seeing the contents of the file, it's hard to say anything. – Azeem Apr 14 '18 at 03:27
  • 1
    I'll edit it now to add the file. The case doesn't matter. If you think it would help I could convert everything to lowercase. – Brian.H Apr 14 '18 at 03:31
  • 1
    "Invalid memory reference (SIGSEGV)", ZZZZZZZZZZZZZZZZZZZZ, I think your program got bigger problem. – Stargateur Apr 14 '18 at 03:37
  • I couldn't upload the file. I changed temp_name[strlen(temp_name) - 1] = '\0'; to temp_name[strlen(temp_name) - 1] = '\n'; but that didn't give a different result. The longest name in the file is just shy of 40 characters. – Brian.H Apr 14 '18 at 03:44
  • Thank you to whoever fixed that format issue with my edit! – Brian.H Apr 14 '18 at 03:49
  • what OS are u using? windows has \r\n at the end whereas linux has only \n probably better to use strpbrk(temp_string, "\r\n") to find end of string – AndersK Apr 14 '18 at 03:59
  • I'm using linux (Ubuntu). – Brian.H Apr 14 '18 at 04:07
  • 1
    you should also check return value of fopen and malloc – AndersK Apr 14 '18 at 04:16
  • @AndersK., The program will only see '\n' regardless of the actual line ending character sequence. – user3629249 Apr 14 '18 at 06:34
  • when reading a text file, the last line might not end with '\n' so should use appropriate code to ONLY overlay the last char with a NUL byte if the last char (before the NUL) is a '\n' – user3629249 Apr 14 '18 at 06:43
  • when calling any of the heap allocation functions: `malloc` `calloc` `realloc` 1) the returned type is `void*` so can be assigned to any pointer. Casting just clutters the code, making it more difficult to understand, debug, etc. 2) Always check (!=NULL) the returned value to assure the operation was successful. If Not successful, call `perror()` to output your error message and the text reason the system thinks the function failed to `stderr` – user3629249 Apr 14 '18 at 06:46
  • The posted code fails to free all those 'malloc()`d allocations before exiting. It is very poor programing practice to leave that clutter for the OS to fix, Strongly suggest adding the necessary logic to cleanup before exiting. – user3629249 Apr 14 '18 at 06:52
  • You should initialize m_z_position. new_node is also not a good name, if u make a typo and forget the _ you enter a complete new ballgame – AndersK Apr 15 '18 at 07:53

2 Answers2

1

I was fixing your code, but as this comment already state, your file use "\r\n" as end line code, can be fixed with str[strcspn(str, "\r\n")] = '\0'; just after your read.

But here, an other exemple of implementation of your code:

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

typedef struct char_node {
    struct char_node *next;
    char name[];
} char_node;

typedef struct char_queue {
    char_node *q_head;
    char_node *q_tail;
    size_t q_size;
} char_queue;

char_node *enqueue(char_queue *q_ptr, char const *new_name);
void print_list(char_queue const *queue);

int main(void) {
    char_queue queue = { .q_head = NULL, .q_tail = NULL, .q_size = 0 };
    char const key[] = "Mark,Zuckerberg";

    FILE *file_input = fopen("party.csv", "r");
    if (file_input == NULL) {
        file_input = stdin;
    }
    char str[40];
    size_t m_z_position = 0;
    while (fgets(str, sizeof str, file_input)) {
        str[strcspn(str, "\r\n")] = '\0';
        if (strcmp(str, key) == 0) {
            m_z_position = queue.q_size;
        }
        enqueue(&queue, str);
    }
    fclose(file_input);

    print_list(&queue);
    printf("m_z_position = %zu\n", m_z_position);
}

char_node *enqueue(char_queue *q_ptr, char const *name) {
    size_t i = strlen(name) + 1;
    char_node *node = malloc(sizeof *node + i);
    if (!node) {
        return NULL;
    }
    strcpy(node->name, name);
    node->next = NULL;

    if (q_ptr->q_size++ == 0) {
        q_ptr->q_tail = q_ptr->q_head = node;
    } else {
        q_ptr->q_tail = q_ptr->q_tail->next = node;
    }
    return node;
}

void print_list(char_queue const *queue) {
    for (char_node const *list = queue->q_head; list; list = list->next) {
        printf("%s\n", list->name);
    }
    printf("\n");
}
Stargateur
  • 24,473
  • 8
  • 65
  • 91
-1

I am afraid that .csv file contains "Mark,Zuckerberg" not Mark,Zuckerberg.

In if(strcmp(temp_name, key) == 0){ key is compared with temp_name. Here key is Mark,Zuckerberg.

int strcmp(const char *s1, const char *s2);

The strcmp() and strncmp() functions return an integer greater than, equal to, or less than 0, according as the string s1 is greater than, equal to, or less than the string s2.

strcmp will return positive number if temp_name is "Mark,Zuckerberg" because it contains additional 2 characters and, 0 if temp_name is Mark,Zuckerberg as key here is Mark,Zuckerberg clearly.

Monk
  • 756
  • 5
  • 16
  • Sorry, the quotes are just there to quote what's in the file. I understand what strcmp returns. I've used it in the past without issue. That's why I'm confused as to why it's not working now. – Brian.H Apr 14 '18 at 03:47
  • OK. try one more thing and please share the result. In while loop after temp_name[strlen(temp_name) - 1] = '\0'; and before if(strcmp(temp_name, key) == 0){ use printf("temp_name: %s %ld key: %s %ld\n", temp_name, strlen(temp_name), key, strlen(key)); – Monk Apr 14 '18 at 03:53
  • It's several lines (I'm assuming 350 lines). Here are a couple of lines it printf, 27 key: Mark,Zuckerberg 15lo-Blocher, 17 key: Mark,Zuckerberg 15 – Brian.H Apr 14 '18 at 04:00
  • It looks like it's not printing temp_name – Brian.H Apr 14 '18 at 04:02
  • I am working on linux machine and I printed using printf("line: %d temp_name: %s %ld key: %s %ld\n", i++, temp_name, strlen(temp_name), key, strlen(key)); and I got line: 255 temp_name: Mark,Zuckerberg 15 key: Mark,Zuckerberg 15 test and at end test program output was m_z_position = 255 – Monk Apr 14 '18 at 04:09
  • Yes! That's what my output should be. I'm also running linux. – Brian.H Apr 14 '18 at 04:13
  • What did you do differently that resulted in m_z_position = 255 ? – Brian.H Apr 14 '18 at 04:15
  • I just copied your test program. I created a file party.csv using vim i.e vim party.csv. Later I copied all the names that you have provided into that file. I got the result when I executed the test program. I did no change except adding printf statement for debugging. – Monk Apr 14 '18 at 04:22