0

I'm trying to create an array of strings and pass strings to this array.

struct node {
    int vertex_no;

};

int main() {
    char city1[100], city2[100], buffer[999];
    int distance;
    FILE *fp;
    fp = fopen("cities.txt", "r+");
    if(fp == NULL)
        perror("Error");
    //Change - characters with space
    while(1) {
        char ch = fgetc(fp);
        if(ch == '-') {
            fseek(fp, ftell(fp)-1, SEEK_SET);
            fputc(' ', fp);
        }

        if(ch == EOF)
            break;
    }

    //Get to beginning of the file
    fseek(fp, 0, SEEK_SET);

    //Pass first line
    fgets(buffer, sizeof(buffer), fp);

    int i, j, v = 0;
    char cities[100][100];
    for(i = 0; i < 100; i++)
        for(j = 0; j < 100; j++)
            cities[i][j] = '\n';
    int vertices = 0;
    int add = 1;
    //Find how many vertices we have
    while(fscanf(fp, "%s %s %d", city1, city2, &distance) == 3) {
        if(cities[0][0] == '\n') {
            strcpy(cities[0], city1);
            strcpy(cities[1], city2);
            v = 2;
        }
        for(i = 0; cities[i][0] != '\n'; i++) {
            //Search city1 inside cities array
            if( strcmp(cities[i], city1) == 0 ) {
                add = 0;                
                break;
            }
            //If not found add it to array
            if(add) {
                strcpy(cities[v], city1);
                v++;
            }
            //Same search for city2
            add = 1;
            if( strcmp(cities[i], city2) == 0 ) {
                add = 0;                
                break;
            }
            //If not found add it to array
            if(add) {
                strcpy(cities[v], city2);
                v++;
            }
        }               
    }

    for(i=0;cities[i][0] != '\n';i++)
        printf("City no.%d = %s\n", i, cities[i]);
    printf("Last city1, city2 and distance: %s, %s, %d", city1, city2, distance);
    return 0;
}

As a result I get

segmentation fault(core dumped)

When I try to do something like this

char *test = NULL;
strcpy(test, "hello");
return 0;

I get the same segmentation fault again. Although when allocate space like this:

char *test = (char *) malloc(100);

There is no problem. But when I do like this:

char test[100];

There is also no problem. So that's why I don't understand the reason of getting segmentation fault even tho I used

char strings[100][100];

instead of

char *strings[100];
Vsky
  • 59
  • 1
  • 9
  • 1
    Possible duplicate of [Definitive List of Common Reasons for Segmentation Faults](http://stackoverflow.com/questions/33047452/definitive-list-of-common-reasons-for-segmentation-faults) – StoryTeller - Unslander Monica Mar 09 '17 at 08:52
  • 1
    Use a debugger to find out *where* the segfault occurs. Examine variables involved in the failed operation. – n. m. could be an AI Mar 09 '17 at 08:57
  • 2
    *Where* do you get the crash? Have you tried running in a debugger to catch the crash "in action"? Please do that to locate where in *your* code the crash happens, as well as to examine the values of all involved variables when it happens. If you still can't figure it out yourself then please edit your question to include that information so we can better help you. – Some programmer dude Mar 09 '17 at 08:58
  • 2
    `for(i = 0; cities[i][0] != '\n'; i++) {` runs possible endless – Holger Mar 09 '17 at 08:58
  • 2
    Your strings don't have null terminators. – Barmar Mar 09 '17 at 08:59
  • 1
    All the `strXXX()` functions work on null-terminated strings, but you don't have them. – Barmar Mar 09 '17 at 09:00
  • 1
    It seems like you're using `\n` when you should have been using `\0`. – Barmar Mar 09 '17 at 09:00
  • 1
    `char ch = fgetc(fp);` is [wrong](http://stackoverflow.com/questions/23513961/detect-end-of-text-file-reading-using-fgetc). – n. m. could be an AI Mar 09 '17 at 09:03
  • @StoryTeller List of common reasons for seg faults is not an exact duplicate of this question. – 2501 Mar 09 '17 at 09:08
  • @2501 - Neither is the definitive reason of unresolved external symbol errors an exact duplicate for that type of question. "Exact" duplicates are rare. – StoryTeller - Unslander Monica Mar 09 '17 at 09:14
  • @StoryTeller Why are you closing it then? – 2501 Mar 09 '17 at 09:15
  • @2501 - Because the OP can get their question answered there. – StoryTeller - Unslander Monica Mar 09 '17 at 09:16
  • Please [edit] your code to reduce it to a [mcve] of your problem. Your current code includes much that is peripheral to your problem - a minimal sample normally looks similar to a good unit test: only performing one task, with input values specified for reproducibility. You also need to `#include` at least one standard header file for it to be complete, too. – Toby Speight Mar 09 '17 at 12:35
  • the posted code does not compile. Amongst other reasons, it is missing the necessary `#include` statements – user3629249 Mar 09 '17 at 23:40
  • the posted code contains some 'magic' numbers. 'magic' numbers are numbers with no basis. I.E. 100. 'magic' numbers make the code much more difficult to understand, debug, maintain. Suggest using a `enum` statement or `#define` statements to give those 'magic' numbers meaningful names, then use those meaningful names throughout the code. – user3629249 Mar 09 '17 at 23:45
  • regarding this line:`while(fscanf(fp, "%s %s %d", city1, city2, &distance) == 3)` something needs to keep track of how many entries are being used in the `cities[][]` array so the code will not try to add more than 100 vertices. this seems to be the variable `v`, so the line should be: `while( v<100 && fscanf(fp, "%s %s %d", city1, city2, &distance) == 3)` – user3629249 Mar 09 '17 at 23:54
  • when calling any of the `scanf()` family of functions, when using the "%s" input conversion specifier, always include a MAX CHARACTERS modifier that is one less than the length of the input buffer. this is to avoid buffer overflow, which would be undefined behavior and can lead to a seg fault event and/or corrupt the following data. – user3629249 Mar 09 '17 at 23:58
  • the input: `distance` is not saved, nor associated with the cities that it was read with. So the code contains a major logic flaw. – user3629249 Mar 10 '17 at 00:13
  • actually, this: `char test[100];` is a problem because it only declares an single array of 100 characters. I.E. only has a location for a single city string – user3629249 Mar 10 '17 at 00:27

1 Answers1

0

Following allocates a single pointer and sets that pointer to point to a single array of 100 characters. I.E. no place to insert 100 city strings.

char *test = NULL;
strcpy(test, "hello");
return 0;

....
char *test = (char *) malloc(100);
....

Following declares an array of 100 bytes with no room for 100 city strings

char test[100];

Following declares an array of 100 character arrays, of which each array is 100 bytes long

char strings[100][100];

Following declares an array of 100 pointers to char, not 100 character strings. So you would need to 'malloc' room for each city string and insert that pointer into the appropriate offset into the array.

char *strings[100];
user3629249
  • 16,402
  • 1
  • 16
  • 17