Reputation: 341
I read words from given file (dictionary) to single string and I assign the string to nth index of string array. But it does not work. Output of the for loop in the main()
is always e3V\347
etc. and output of the for loop in the createWordTable()
is always last word of dictionary. Here is my code
char** createWordTable();
char** createTable();
int main()
{
int i;
char **hashTable;
hashTable = createTable();
hashTable = createWordTable();
for (i=0; i< 338; i++) {
printf("%s \n",hashTable[i]);
}
return 0;
}
char** createWordTable(){
char word[20],**table;
FILE *dicFile;
table = createTable();
dicFile = fopen("smallDictionary.txt", "r");
if (dicFile == NULL) {
perror("error");
}
int wordCount = 0,endFile = 1;
while (endFile != EOF) {
endFile = fscanf(dicFile,"%s",word);
table[wordCount] = word;
wordCount = wordCount+1;
}
for (int i=0; i< 338; i++) {
printf("%s \n",table[i]);
}
return table;
}
char** createTable(){
char **table;
int i;
table = (char **)malloc(338 * sizeof(char *));
for (i=0; i<=338; i++) {
*table = (char *)malloc(25 * sizeof(char));
}
return table;
}
I changed code to this and its work! I defined global variable 'table' and removed pointers (also dynamic allocation functions). I'm very curious why pointers don't work with array of strings in C for this code (I know square brackets also mean 'pointer') ? Because i have no bad experience with integer arrays. Sorry for bad English, here is new code :`
char words[338][10];
int main()
{
createWordTable();
for (int i=0; i< 338; i++) {
printf("%s \n",words[i]);
}
return 0;
}
void createWordTable(){
char word[20];
FILE *dicFile;
dicFile = fopen("smallDictionary.txt", "r");
if (dicFile == NULL) {
perror("error");
}
int wordCount = 0;
while (!feof(dicFile)) {
fscanf(dicFile,"%s",word);
if(feof(dicFile)) break;
strcpy(words[wordCount], word);
wordCount = wordCount+1;
}
fclose(dicFile);
}`
Upvotes: 3
Views: 1276
Reputation: 43014
An option to return an array of strings from a function is to use double-NUL
-terminated strings.
This data structure is a sequence of strings, one stored in memory after the other, each NUL
-terminated, and with an additional NUL
-terminator at the end, e.g.:
+---+---+---+---+---+-----+---+---+---+---+---+-----+-----+
| H | e | l | l | o | NUL | w | o | r | l | d | NUL | NUL |
+---+---+---+---+---+-----+---+---+---+---+---+-----+-----+
^^^^^^
Double-NUL at the end
You can return from the function the pointer to the first string, i.e. to the beginning of the sequence.
One of the great advantages of this data structure is that it has very good locality for strings in the array.
This data structure is not hard to implement, and it's easy to navigate, as you can see from the following source code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
char * build_string_array(void) {
const char * test_strings[] = {
"Hello",
"World",
"Hi",
"John",
"Connie"
};
int i;
char * p;
char * string_array;
int total_len;
/* Calculate total length of strings */
total_len = 0;
for (i = 0; i < ARRAY_SIZE(test_strings); i++) {
/* Update total length with current string. +1 for '\0' */
total_len += strlen(test_strings[i]) + 1;
}
/* Consider double-NUL termination */
total_len++;
/* Allocate memory for the resulting string array */
string_array = malloc(total_len);
if (string_array == NULL)
return NULL; /* error */
/* Copy source strings to the destination string array memory */
p = string_array;
for (i = 0; i < ARRAY_SIZE(test_strings); i++) {
strcpy(p, test_strings[i]);
p += (strlen(p) + 1); /* +1 to skip terminating NUL */
}
/* Terminate with double-NUL */
*p = '\0';
/* Return the address of the string array to the caller */
return string_array;
}
int main() {
char * test_string_array;
const char * p;
/* Create the test string array */
test_string_array = build_string_array();
if (test_string_array == NULL) {
printf("Error in creating array.\n");
return 1;
}
/* Print string array content */
for (p = test_string_array; *p != '\0'; p += (strlen(p) + 1)) {
printf("%s\n", p);
}
/* Free array memory */
free(test_string_array);
/* All right */
return 0;
}
Upvotes: 1
Reputation: 4482
You should fscanf
directly into table[wordcount]
or strcpy
from word
. Otherwise every entry will just point to word, which contains the last string in the file.
Upvotes: 0
Reputation: 605
You are losing your createTable() result. Store it separate pointer variables.
hashTable = createTable();
hashTable = createWordTable();
Upvotes: 1