0
struct dict {
    int len;
    char (*dict0)[MAX_WORD_LEN+1];
    char (*dict1)[MAX_WORD_LEN+1];
};

/* the memory allocation */
void createDict(struct dict* myDict)
{
    (*myDict).dict0 = malloc((*myDict).len*sizeof(char));
    (*myDict).dict1 = malloc((*myDict).len*sizeof(char));
    if(((*myDict).dict0==0)||((*myDict).dict1==0))
        exit(1);
}

for(int i = 0; i < words; i++)
{
   scanf("%s", p_diction->dict0[i]);
   scanf("%s", p_diction->dict1[i]);
}

for(int i=0; i<words; i++)
{
   printf("%s ", &p_diction->dict0[i]);
   printf("%s\n", &p_diction->dict1[i]);

}

p_diction是一个dict类型的指针。

我设置words为 11 并输入以下内容:

one lo
two ba
three li
day night
work eat
great terrible
terrible disaster
A a
start delay
finish never
I you

但是当我printf检查字符串时,它们会打印以下内容:

one ree
two y
three rk
day eat
work rrible
great terrible
terrible art
A nish
start delay
finish never
I you

关于为什么第一个scanf能完美地阅读它,而第二个只是从稍后出现的单词中读取随机内容的任何想法?

4

2 回答 2

0

看起来您正在使用一维数组来保存多个字符串(单词),如果您以表示单词结尾的唯一字符结束每个字符串(单词),这是可能的。但是使用 vanilla 函数 scanf() 和 printf() 是不可能做到这一点的,你必须自己编写。例如,假设您以 @ 结束每个单词。以下循环会将所有单词打印到您的屏幕上。

int i = 0;
while((*myDict).dict0[i] != '\0')//While index dose not point to end of array
{
  for(; (*myDict).dict0[i] != '@'; i++)//Print one word a single character at a time
  {
    printf("%c", (*myDict).dict0[i]);
  }
  printf("\n"); i++;//Print a newline after the word and then increase the index by one
                    //so that it does not point to '@'.
}

但是你也可以将你的 dict0 和 dict1 数组变成指针数组,其中每个元素都是一个指向单个单词的指针。

于 2013-01-13T21:40:01.300 回答
0

您正在重新声明 i 并且不需要(对于 printf 循环)。对于第二个循环,我已经存在,因此i=0足以“重新初始化”变量。

关于读取循环,scanf如果您使用 enter/return 分隔单词,则它是“安全的”。如果你用空格分隔它们,scanf 不是一个好的选择。第二个 scanf 正在寻找该输入/返回,如果您不通过标准输入提供它,它将失败并且它可能会存储垃圾,直到找到输入/返回(\n)。

还有一件事,你是如何声明的pdiction?如果你这样做:

struct dict *pdiction = malloc(sizeof(struct dict));

您可以通过以下方式访问其“内部”变量:

pdiction->len = 10; /*Setting len to 10*/

但如果你声明它,在与读/写循环相同的函数中,如下所示:

struct dict pdiction;

您可以通过以下方式访问“内部”变量:

pdiction.len = 10;

第二种方式是通常如何访问 C 结构。所谓的点符号。第一种方式有点像 C 的演变:使用“在字段中指向的”作为指向结构的指针是如此普遍,以至于 C 为您提供了一种更好/更容易/更易读的方式:箭头符号。我在第一种情况下写的内容与以下内容完全相同:

(*pdiction).len = 10; /*The (structure) pointed by pdiction in the field len*/

所以要小心。

最后,我认为您是故意这样做的,但是 printf 可能正在打印内存地址而不是实际的字符串,因为您使用的是内存地址“选择器”与符号。

[编辑] - 看到您的编辑后,我可以看到一个可能的错误。如果在您的结构中您已使用静态值声明了字符串:

char (*dict0)[MAX_WORD_LEN+1];
char (*dict1)[MAX_WORD_LEN+1];

您不需要为它们“重新分配”空间。您需要的是有一个字符串向量或一个字典向量。访问pdiction->dict[i]只是一个字符。如果你想要一个向量,你需要改变你的分配。

我会通过仅在结构中声明指针并稍后进行向量分配而不是拥有dicts(structs)的向量来做到这一点。

您可以通过将结构更改为此:

struct dict {
    int len;
    char **dict0;
    char **dict1;
};

然后你必须在函数中分配你的向量:

pdiciton->dict0 = malloc(NUMBER_OF WORDS * sizeof (char*));
for(i=0;i<NUMBER_OF_WORDS;i++)
   pdiction->dict0[i] = malloc(MAXIMUM_SIZE_OF_A_WORD*sizeof(char));

dict1 也一样。这可能看起来很奇怪,但如果你仔细想想,这实际上是一个逻辑:如果一个字符串是一个字符向量,那么一个字符串向量就是一个字符矩阵。

不过,scanf 的问题似乎是一样的:使用 enter/return 是安全的,但不是空格。尝试使用 enter/return next 而不是空格插入所有数据,看看它是否有效。

希望这可以帮助。

于 2013-01-13T21:15:15.800 回答