1

嗨,所有 stackoverflow 用户。我正在尝试构建一个简单的(作为练习)代码,该代码将从文件中读取并将文件中的单词存储在动态分配的数组中。我想我分配错了。有谁看到我做错了什么?

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

#define ARRSIZE 10

int main(){
    char * myArray = malloc(ARRSIZE*sizeof(char*));
    FILE * p1File;
    char mystring1 [100];
    char word [100];
    int j = 0;
    p1File = fopen ("my1file.txt","r");
    if (p1File == NULL) perror ("Error opening file");
    else{
        while(fgets(mystring1, 100, p1File)){
            int nuRead = sscanf(mystring1, "%s", word);\
            printf("lepo ani magia\n\n");
            if (nuRead > 0){
                strncpy (*myArray[j], mystring1, 100);
                //*myArray[j] = mystring1;
            }
            j += 1;
        } 
    }
}

//////////////////////////////

my text file is

this
will
probably
work
but
I
am
4

4 回答 4

3

对于这个任务,我将首先定义一个包含单词的数据结构,如下所示:

struct wordlist {
    char **words; /* the actual words */
    size_t size; /* the number of words in the list */
    size_t capacity; /* the number of words that would fit in the list */
};
typedef struct wordlist wordlist;

然后我会定义一些函数来对它们进行操作。这是为了保持代码main简短易读。功能是:

void *
malloc_or_fail(size_t size)
{
  void *result = malloc(size);
  if (result == NULL) {
    perror("malloc");
    exit(EXIT_FAILURE);
  }
  return result;
}

/* Creates a newly allocated copy of the given string. Later changes
 * to the given string will not have any effect on the returned string.
 */
char *
str_new(const char *str) {
  size_t len = strlen(str);
  char *result = malloc_or_fail(len + 1);
  memcpy(result, str, len + 1);
  return result;
}

/* Adds a copy of the given string to the word list. Later changes
 * to the given string have no effect on the word in the word list.
 */
void
wordlist_add(wordlist *wl, const char *word)
{
  if (wl->size == wl->capacity) {
    /* TODO: resize the wordlist */
  }
  assert(wl->size < wl->capacity);
  wl->words[wl->size++] = str_new(word);
}

/* Creates a new word list that can hold 10 words before it will be
 * resized for the first time.
 */
wordlist *
wordlist_new(void)
{
  wordlist *result = malloc_or_fail(sizeof wordlist);
  result->size = 0;
  result->capacity = 10;
  result->words = malloc_or_fail(result->capacity * sizeof result->words[0]);
  return result;
}

使用这些功能完成最初的任务应该不难。

于 2010-11-23T18:55:57.613 回答
1

您没有为字符串分配空间,只是为字符串数组分配空间。myArray[j]只是一个未初始化的指针。相反,为每个字符串分配空间,myArray如下所示:

char *myArray[ARRSIZE]; // No reason for this to be dynamic.
// ...
if (nuRead > 0)
{
    myArray[j] = malloc((strnlen(mystring, 100) + 1) * sizeof(char));
    strncpy (myArray[j], mystring1, nuRead + 1);
}

正如 user411313 指出的那样, sscanf 不返回匹配的字符数,而是匹配的输入项数。使用strnlen(或者strlen如果你没有strnlen)获取字符串的大小(并且不要忘记为空终止符添加 1)。

于 2010-11-23T18:35:50.250 回答
0
char * myArray = malloc(ARRSIZE*sizeof(char*));

你已经分配了一个地方来存储十个字符串指针。但是您没有分配任何空间来将字符复制到持久字符串中。

如果您想在开始时设置该存储,您可以这样做

#define MAX_STR_SIZE 100

char * myArray = malloc(ARRSIZE*sizeof(char*));
if (!myArray) exit(1);
for (j=0; j<ARRSIZE; j++) {
    myArray[j] = malloc(MAX_STR_SIZE);
    if (!myArray[j]) exit(1);
}

或者,可能更好的是,您可以根据需要分配每个字符串。而不是strncpy, 使用strdup(这就像做 amalloc然后 a strcpy):

    myArray[j] = strdup(mystring1);
于 2010-11-23T18:39:00.657 回答
0

如果您只需要处理最多 10 行文本,那么我会这样做:

char *myArray[ARRSIZE];
...
if (nuRead > 0) {
  myArray[j++] = strdup(mystring1);
}
...

发生的事情是这段代码一次性分配和复制(使用strdup,而不是malloc后跟strcpy)。

于 2010-11-23T18:43:58.803 回答