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*));

10個の文字列ポインタを格納する場所を割り当てました。ただし、文字を永続文字列にコピーするためのスペースは割り当てられていません。

最初にそのストレージをセットアップしたい場合は、

#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、 ( thenをstrdup実行するようなものです)を使用します。mallocstrcpy

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

最大 10 行のテキストのみを処理する必要がある場合は、次のようにします。

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

何が起こっているかというと、このコードは ( mallocの後にstrcpyが続くのではなく、strdupを使用して) 割り当てとコピーを一度に行うということです。

于 2010-11-23T18:43:58.803 に答える