这就是文件中文本的样子:
locked y
locked n
position 90
position 2
audio-language "english"
audio-language "spanish"
每个文本文件只包含上面显示的一种设置,区别在于选项(y或n,1到999,“英语”“西班牙语”“其他任何”)它前面有4个空格和一个每行末尾的新行,所以我需要一个fscanf,它将在char数组字符串中提取参数,但我似乎无法理解如何正确使用分隔符。我必须制作一个程序,可以扫描该文件并打印不同的设置以及在文件中找到它们的次数,例如:
audio-language is found with setting: "spanish" 40 times
audio-language is found with setting: "english" 78 times
比你们所有人的答案都要好!在这里,我可以告诉你我是如何工作的:
1 - 首先你使用一个功能(我在互联网上找到)消除了设置前面的空白区域:
char* ltrim(char* s)
{
char* newstart = s;
while (isspace( *newstart)) {
++newstart;
}
// newstart points to first non-whitespace char (which might be '\0')
memmove( s, newstart, strlen( newstart) + 1); // don't forget to move the '\0' terminator
return s;
}
2 - 然后fscanf没有问题,让线路正确:
while(!feof(fpoo)) {
fscanf(fpoo,"%s %[^\n]",&first, &sec);
3 - 然后你将fscanf得到的那些与用户输入的那些进行比较
就是这样,显然 fscanf 的整个问题是因为每行前面都有空格。
答案 0 :(得分:2)
我编译了这段代码并对其进行了测试。完美的工作。你也可以测试它:))
int main()
{
int bytes_read = 0, english_count = 0, spanish_count = 0;
char file_buffer[256], setting[127], option[32], fileName[32] = "FileName.txt";
FILE *fp;
if((fp = fopen("FileName.txt", "rb")) <=0)
{
printf("Unable to open the File\n");
}
//rewind(fp);
while(fgets (file_buffer, 50, fp))
{
sscanf(file_buffer,"%s %s",setting,option);
printf("Setting: ");
printf("%s",setting);
printf("\nOption: ");
printf("%s",option);
printf("\n\n");
if(memcmp(setting,"audio-language",14) == 0)
{
if(memcmp(option,"english",7) == 0)
{
english_count = english_count+1;
}
if(memcmp(option,"spanish",7) == 0)
{
spanish_count = spanish_count+1;
}
}
//you can add more checks here.
}
printf("\naudio-language is found with setting: english ");
printf("%d",english_count);
printf("\naudio-language is found with setting: spanish ");
printf("%d",spanish_count);
printf("\n");
return 0;
}
答案 1 :(得分:0)
检查算法,你必须编码
我认为这可以解决您的问题。
答案 2 :(得分:0)
您可以先将字符串读入:
scanf("%[^\n]s",buffer)
现在,您可以使用C中的标记生成器通过 strtok
获取语言的值char *token="\n";
token = strtok(line, token);
现在,令牌将包含所有拆分字,您可以将strcmp与可能的语言进行比较并保持计数
答案 3 :(得分:0)
您评论中的人是对的。你真的应该向我们展示你的尝试。如果这是家庭作业,那么你就不能作弊,因为你的讲师可能会通过简单的谷歌搜索来破坏你。期望我们在这里猜测你的理解并涵盖你已经涵盖的内容是浪费的,所以告诉我们你做了什么。
qsort
,bsearch
和strcmp
提供了一种简单,相对有效的排序&amp;搜索机制,用于以字符串开头的任何内容(例如,以字符串为前缀的结构)。格式字符串中的空格告诉fscanf
消耗尽可能多的空格。 fscanf
返回一个指示成功和失败模式的值,这意味着您不一定需要将每行读入一个字符数组,以测试输入是否与特定格式匹配。但是,您需要注意设计文件,以便所有命令都没有其他命令的公共前缀。在这种情况下,你是安全的。
这是我的尝试。快乐的调试:)
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct language_table { char language[64]; size_t count; };
struct language_table *parse(FILE *f, size_t *s);
int main(void) {
size_t s;
struct language_table *t = parse(stdin, &s);
while (s-- > 0) {
printf("audio-language is found with setting: %s %zu times\n", t[s].language, t[s].count);
}
free(t);
}
struct language_table *parse(FILE *f, size_t *s) {
char locked, language[64];
unsigned int position;
int c = 0;
struct language_table *table = NULL, *entry;
size_t size = 0;
do {
if (fscanf(f, " locked %c", &locked) == 1 && strchr("ynYN", locked)) {
/* XXX: Do something with locked. */
}
else if (fscanf(f, " position %u", &position) == 1) {
/* XXX: Do something with position. */
}
else if (fscanf(f, " audio-language %63s", language) == 1) {
/* search for the language in table. */
entry = bsearch(language, table, size, sizeof *table, strcmp);
/* insert the language if it's not found. */
if (entry == NULL) {
if ((size & (size + 1)) == 0) {
void *new = realloc(table, (size * 2 + 1) * sizeof *table);
if (new == NULL) {
fprintf(stderr, "failed to allocate new entry for %s\n", language);
free(table);
return NULL;
}
table = new;
}
entry = table + size++;
strcpy(entry->language, language);
entry->count = 0;
/* sort & search */
qsort(table, size, sizeof *table, strcmp);
entry = bsearch(language, table, size, sizeof *table, strcmp);
}
entry->count++;
}
else {
/* consume an invalid line */
do {
c = fgetc(f);
} while (c >= 0 && c != '\n');
}
} while (c >= 0);
*s = size;
return table;
}