0

我试图编写一个函数,它可以获取 10 到 60,000 之间的候选者数量,并为每个候选者获取一个名称......这就是我写的:

/********** Headers **********/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <conio.h>
/********** Consts **********/
const number_candidates;

/********** Functions **********/
void get_candidates(char *arr[256][256])
{
    int counter = 1, i = 0, j =0;
    int temp = 0;

    printf ("Please enter the number of candidates: \n");
    scanf ("%d", &temp);
    while (temp < 10 && temp > 60000)
    {
        printf ("Please enter the number of candidates: \n");
        scanf ("%d", temp);
    }
    const number_candidates = temp;
    while (counter < number_candidates + 1)
    {
        printf ("Please enter the %d name: \n", counter);
        fgets (arr, 256, stdin);
        counter++;
    }
}

int main(int argc, char *argv[])
{
    int i = 0;
    char can_names[256][256];

    get_candidates(&can_names);

    system("PAUSE");
    return 0;
}

将名称输入 arr 时出错...

4

5 回答 5

2

你应该避免使用这样char *arr[256][256]的论点:......它有什么意义?你应该考虑你的函数会做什么。您希望它加载候选人的姓名吗?因此,您可以在其中定义具有属性的struct Candidatename

typedef struct candidate{
    char name[256];
} Candidate;

另一件事:为什么要将数组的地址传递给这个函数?您只希望您的数组充满数据,您不会使用数组本身,因此传递一个数组而不是它的地址就足够了。

然后可以将您的函数原型更改void get_candidates(Candidate* candidates)为更易于阅读的原型。看看这个函数的使用变得多么简单:

Candidate candidates[256];
get_candidates(candidates);

最后一件事:在你编写这样的函数之前,先尝试一些更简单的东西(找出那里发生了什么)。这是一个例子:

#include <stdio.h>

typedef struct candidate{
    char name[256];
} Candidate;

void get_candidates(Candidate* candidates){
    scanf("%255s", candidates[4].name);
}

int main(int argc, char *argv[]){
    Candidate candidates[256];
    get_candidates(candidates);
    printf("%s\n", candidates[4].name);
    return 0;
}

如果您在调用之前不知道候选者的数量get_candidates,那么最好将此函数的原型更改为,Candidate* get_candidates()以便清楚地知道该函数创建了一个数组:

// caller is responsible for calling free on return value
Candidate* get_candidates(){
    Candidate* candidates;
    int count = 50; // here you found out the count
    candidates = malloc(count*sizeof(Candidate));
    fgets(candidates[4].name, 255, stdin);
    return candidates;
}

int main(int argc, char *argv[]){
    Candidate* candidates = get_candidates();
    printf("%s\n", candidates[4].name);
    free(candidates);
    return 0;
}
于 2012-05-09T18:45:19.987 回答
0

查看文档,scanf其中表明变量需要作为指针传递,就像您第一次调用 scanf 时所做的那样。然后看看你对 scanf 的第二次调用......

您目前只是一遍又一遍地为数组中的第一个字符串分配名称。看看那个 while 循环,特别是你是如何传递 'arr' 变量的。看看这里以获得一些灵感。

要打印出您需要遍历数组的所有名称。您可以在此处此处找到打印字符串列表的一些示例。

于 2012-05-09T18:31:04.353 回答
0

您应该致电:

counter = 0;
...
fgets (arr[counter], 256, stdin);


您需要为每个循环走一步。

于 2012-05-09T18:37:21.487 回答
0

有几点是不对的:

首先,您需要为 60000 个名称分配空间,但您只分配了足够 256 个名称。好的,我们更改

char can_names[256][256];

char can_names[60000][256];

并得到...一个分段错误,可能。那是因为数组使用了太多的堆栈空间。将其更改为

static char can_names[60000][256];

所以它不在堆栈上。


其次,不需要获取数组的地址——它已经作为指针传递了。您的函数调用更改为

get_candidates(can_names);

并且函数签名是

void get_candidates(char arr[60000][256])

第三,您需要一个循环来一次读取一个条目。循环更for容易阅读:

for (counter = 0; counter < number_candidates; counter++)
{
    printf ("Please enter the %d name: \n", counter);
    fgets (arr[counter], 256, stdin);
}

四、条件

while (temp < 10 && temp > 60000)

应该

while (temp < 10 || temp > 60000)

(一个数字怎么可能既小于 10 又大于 60000?)一旦解决了这个问题,您就可以删除初始读取,temp因为循环将至少运行一次。请注意,如果您现在键入字母而不是数字,程序将进入无限循环(它将重复读取字母)。解决这个问题留作练习。


第五,您不需要任何标题,除了stdio.h. 此外,ij变量未使用。


编辑:错过了scanf错误。 scanf地址作为参数。这也很有意义:scanf需要某个地方来存储一个值,它不关心当前值。所以调用scanf应该是:

scanf ("%d", &temp);
于 2012-05-09T18:46:38.723 回答
0

不知道这是否会有所帮助,但请查看下面的代码。它是动态工作的,即。它为所需的候选人分配内存,而不是假设其中有 60,000 个。

/*
 * Write a function, that get a number of candidates betwen 10 to 60,000, and gets a     name for each candidate 
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX 256

int main(int argc, char*argv[]){

int i,n;
char **s;

printf("Enter the total number of candidates\n");
scanf("%d",&n);

//error condition
if(n<10 || n>60000){        
    printf("Sorry number of candidates should be between 10 to 60,000\n");
    return -1;      
}

//allocate memory
s = malloc(sizeof(char*)*n);

//get the data
for(i=0;i<n;i++){

    s[i] = calloc(MAX,sizeof(char));
    printf("Enter the candidate number %d's name:\n",i+1);
    //fgets(s[i],MAX,stdin);
    scanf("%s",s[i]);

}

//Display the data
printf("\nDetails of all the Candidates\n\n");
for(i=0;i<n;i++){
    printf("Candidate number %d's name:%s\n",i+1,s[i]);
}

//Free the memory
for(i=0;i<n;i++){
    free(s[i]);
}
free(s);

return 0;

}

我遇到了 fgets 的问题,它跳过了第一个候选人信息。任何帮助将不胜感激。我试过flush(stdin)但没有解决问题。

于 2012-05-10T09:29:59.903 回答