'Getting strings from file gone wrong
The idea of this function is to get strings from file like this:
The file CLIENTS_BOOK: client1,client2,client3
and to get this in array of strings, eg:
CLIENTS_BOOK_ARRAY[i]to be equal to"client1"CLIENTS_BOOK_ARRAY[i+1]to be equal to"client2"CLIENTS_BOOK_ARRAY[i+2]to be equal to"client3"
Here is the code:
//global array
static char CLIENTS_BOOK_ARRAY[MAX_SIZE_OF_ARRAYS][MAX_SIZE_OF_ARRAYS];
void get_clients_string() {
int i = 0;
int n = 0;
char *token;
char help[256];
FILE *InputFile;
InputFile = fopen(CLIENTS_BOOK, "r");
fscanf(InputFile, "%s", help);
token = strtok(help, ",");
while (token != NULL) {
strncpy(CLIENTS_BOOK_ARRAY[i], token, MAX_SIZE_OF_ARRAYS);
token = strtok(NULL, ",");
i++;
}
n = i;
fclose(InputFile);
}
When I run it, it is giving
Segmentation fault(core dumped)
When running it with gdb it is giving
Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7f2ce38 in __strncpy_avx2_rtm () from /usr/lib/libc.so.6
The interesting part comes when it is running as intended on my pc (Arch linux, amd cpu), and it does not on my laptop (Arch linux, intel cpu).
Solution 1:[1]
There are multiple problems in your code:
you do not test the return value of
fopen(). If the file cannot be open,InputFilewill be a null pointer andfscanf()will have undefined behavior.fscanf(InputFile, "%s", help);will write beyond the end of thehelparray if the word in the file has 256 bytes or more. Use this instead:fscanf(InputFile, "%255s", help);or possibly:
fgets(help, sizeof help, InputFile);and test for failure to read the file contents.
strncpyis not your friend:strncpy(CLIENTS_BOOK_ARRAY[i], token, MAX_SIZE_OF_ARRAYS)will not null terminate the string if it happens to be longer thanMAX_SIZE_OF_ARRAYS - 1bytes. Do not usestrncpy, usestrncat,snprintforstrlcpyif available instead.the loop does not stop at the end of the 2D array: you should check that
i < MAX_SIZE_OF_ARRAYSin thewhiletest.
Here is a modified version:
#include <stdio.h>
#include <string.h>
#define CLIENT_SIZE 100
#define CLIENT_NUMBER 100
#define CLIENTS_BOOK "client_book.txt"
static char client_book[CLIENT_NUMBER][CLIENT_SIZE];
int get_clients_string(void) {
int n = 0;
char buf[256];
FILE *InputFile = fopen(CLIENTS_BOOK, "r");
if (InputFile == NULL) {
fprintf(stderr, "error opening %s: %s\n",
CLIENTS_BOOK, strerror(errno));
return -1;
}
if (fgets(buf, sizeof buf, InputFile)) {
char *token = strtok(help, ",\n");
while (n < CLIENT_NUMBER && token != NULL) {
client_book[n][0] = '\0';
strncat(client_book[n], token, CLIENT_SIZE - 1);
token = strtok(NULL, ",");
n++;
}
} else {
fprintf(stderr, "%s: no clients\n", CLIENTS_BOOK);
}
fclose(InputFile);
return n;
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |
