您有一个文本文件,例如:dataBaseSmall.txt
,其中包含您的N个朋友的姓名及其相应的手机号码,格式如下。(名称(无空格(后接空格和相应的电话号码(如下
Kalimohan +917555501305
Bhooshit +918555346394
Ahsan +919055511641
Duranjaya +919155578267
Jahan +919655526742
Bharat +918555026818
您的任务是编写一个程序,读取给定的文件并按字典顺序打印名称。
示例:
输入:dataBaseSmall.txt
6
其中dataBaseSmall.txt包含N=6个好友的详细信息。
Kalimohan +917555501305
Bhooshit +918555346394
Ahsan +919055511641
Duranjaya +919155578267
Jahan +919655526742
Bharat +918555026818
输出:
Ahsan
Bharat
Bhooshit
Duranjaya
Jahan
Kalimohan
说明:这些名字是按字典顺序印刷的。
我的代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct Friend{
char name[20];
char mobile[20];
};
typedef struct Friend Friend;
//feel free to use string functions such as strlen, strcmp etc.
//create functions and modularize your solution.
//solving this problem should take you a good amount of time. Have patience and take it as a challenge.
int main(){
char filename[100], str[100];
int N;
FILE* fp;
Friend* myFriends = (Friend*)malloc(N*sizeof(Friend));
scanf("%s", filename);
scanf("%d", &N);
fp = fopen(filename, "r");
fscanf(fp, "%s", *myFriends);
fprintf
fclose(fp);
return 0;
}
首先,正如ctober19th所指出的,您在初始化值N
之前使用它,这意味着它在对malloc(N * sizeof(Friend))
的调用中会有一个垃圾值。此外,您将无法在对fscanf()
的一次调用中读取整个文件,您需要使用while循环来获取文件的每一行,并(可能(将输入存储在数组中。最后,一旦你读过struct Friend
的数组,你就需要写一个函数来对它们进行排序。然而,我并没有为你写这段代码,因为我觉得这是学校的作业。
您有一个良好的开端,但您应该等到从用户读取了N
之后,再尝试分配Friend
结构的数组:
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct Friend {
char name[20];
char mobile[20];
};
typedef struct Friend Friend;
int main() {
char filename[100];
int i, N;
// read the parameters
if (scanf("%99s", filename) != 1)
return 1;
if (scanf("%d", &N) != 1)
return 1;
// allocate the array
Friend *myFriends = (Friend *)malloc(N * sizeof(Friend));
if (myFriends == NULL)
return 1;
// open the file
FILE *fp = fopen(filename, "r");
if (fp == NULL) {
fprintf(stderr, "cannot open %s: %sn", filename, strerror(errno));
return 1;
}
// read the data
for (i = 0; i < N; i++) {
if (fscanf("%19s %19s", myFriends[i].name, myFriends[i].mobile) != 2) {
fprintf(stderr, "cannot read record %dn", i + 1);
break;
}
}
// sort the array
...
// print the names
...
fclose(fp);
return 0;
}
让我们一步一步来解决这个问题:
- 读取文件
- 创建
Friend
阵列 - 对数组进行排序
- 打印已排序的名称
我已经开始创建一个名为FileResult
:的结构
#include <studio.h>
#include <string.h>
#include <stdlib.h>
#define LINE_BUFFER_SIZE 256
#define INITIAL_LINE_COUNT 1000
struct FileResult
{
char **lines; // array of strings, each string is one line
int linecount; // number of lines
int succeeded; // read status, 0: unsuccessful
};
typedef struct FileResult FileResult;
现在,让我们阅读该文件。我创建了一个名为readfile()
:的函数
FileResult readfile(char filename[])
{
FILE *fp;
char buffer[LINE_BUFFER_SIZE];
FileResult result;
// Initialize number of lines to 0
result.linecount = 0;
fp = fopen(filename, "r");
if (fp == NULL)
{
//Failed
result.succeeded = 0;
return result;
}
// Allocate memory for pointers to strings(lines)
result.lines = malloc(INITIAL_LINE_COUNT * sizeof(char *));
while (fgets(buffer, LINE_BUFFER_SIZE, fp))
{
// Get line length
int len = strlen(buffer);
// Allocate memory as large as the line count + 1 for null termination character
result.lines[result.linecount] = malloc(len * sizeof(char) + 1);
//Copy read line to lines array
strcpy(result.lines[result.linecount], buffer);
//Increment number of lines
result.linecount++;
}
// Shrink unused memory
result.lines = realloc(result.lines, result.linecount * sizeof(char *));
fclose(fp);
result.succeeded = 1;
return result;
}
接下来,我将创建一个createFriends()
函数,该函数将解析每一行并创建一个变量Friend
,然后返回一个动态分配的数组。我使用了strtok()
函数在空间上分割字符串:
Friend* createfriends(char **lines, int linecount)
{
// Allocate space for as many friends as there are lines
Friend *friends = malloc(sizeof(Friend) * linecount);
int i;
for (i = 0; i < linecount; i++)
{
//strtok is used to split the string on the specified delimiters
// " " and "n" are used as delimiters
friends[i].name = strtok(lines[i], " n");
friends[i].mobile = strtok(NULL, " n");
}
return friends;
}
接下来,创建一个函数,告诉排序函数如何比较两个Friend
实例:
//Compare function to be used for sorting (compares by name)
int friendcompare(const void *f1, const void *f2)
{
Friend *friend1 = (Friend *)f1;
Friend *friend2 = (Friend *)f2;
return strcmp(friend1->name, friend2->name);
}
我们的最后一个函数叫做freefileresult()
,它删除为存储文件行而分配的内存。(必须释放动态分配的内存以防止内存泄漏(:
void freefileresult(FileResult result)
{
int i;
for(i = 0; i < result.linecount; i++)
{
free(result.lines[i]);
}
free(result.lines);
}
最后,我们有了main()
函数,它调用了上述所有函数并完成了这项工作。将filename.txt
替换为输入文件的名称:
int main()
{
char filename[100];
int i;
FileResult result;
Friend *friends;
//Step 1: Read the file
result = readfile("filename.txt");
//Check if read successful
if (!result.succeeded)
{
printf("Could not read file");
return EXIT_FAILURE;
}
// Step 2: Create a friends array from the file lines
friends = createfriends(result.lines, result.linecount);
// Step 3: Sort the array using the inbuilt qsort function (quick sort)
qsort(friends, result.linecount, sizeof(Friend), friendcompare);
// Step 4: Print sorted names
for (i = 0; i < result.linecount; i++)
{
printf("n%s", friends[i].name);
}
// Step 5: Free allocated memory
free(friends);
freefileresult(result);
return 0;
}