【问题标题】:C programming- read from text fileC 编程 - 从文本文件中读取
【发布时间】:2016-08-10 14:28:05
【问题描述】:

这是关于从文本文件中读取。

我有 3 个命令行参数:

  1. 文本文件名
  2. 延迟时间
  3. 要读取多少行。

我想通过用户指定的行号读取该文本文件,直到文本文件结束。

例如,我第一次读取 5 行,然后程序询问 how many line(s) do you want to read?。我会输入 7 它读取第 5 到 12 行。

这将重复直到文件结束。

#include <stdlib.h>
#include <stdio.h>
#include<time.h>
#include <string.h>
void delay(unsigned int mseconds)
{
clock_t goal = mseconds + clock();
while (goal > clock());
}
int countlines(const char *filename) {
FILE *fp = fopen(filename, "r");
int ch, last = '\n';
int lines = 0;

if (fp != NULL) {
    while ((ch = fgetc(fp)) != EOF) {
        if (ch == '\n')
            lines++;
        last = ch;
    }
    fclose(fp);
    if (last != '\n')
        lines++;
}
return lines;
}
int main(int argc, char *arg[])
{
FILE *ptDosya;
char ch;
ch = arg[1][0];
int s2;
int satir = 0;
int spaceCounter=0;
int lineCount, x = 0;
lineCount = atoi(arg[3]);
s2 = atoi(arg[2]);
printf("dosya %d satir icerir.\n", countlines(arg[1]));
ptDosya = fopen(arg[1], "r");
if (ptDosya != NULL)
{
    while (ch != EOF&& x < lineCount)
    {
        ch = getc(ptDosya);
        printf("%c", ch);
        if (ch == '\n')
        {
            delay(s2);
            x++;
        }
    }
    while (x < countlines(arg[1]))
    {
        printf("satir sayisi giriniz:");
        scanf("%d", &lineCount);
         // i don't know what should i do in this loop..
    x=x+lineCount;
    }
} 

else {
    printf("dosya bulunamadi");
}
printf("\n\nend of file!\n");
fclose(ptDosya);
return 0;
system("PAUSE");
}

【问题讨论】:

  • 你能告诉我们这段代码有什么问题吗? (我看到一个:你的延迟循环是一个 CPU 密集型循环,不是很好!)
  • 它需要一些补充。此代码在文本结束前不询问时采用行号。

标签: c text


【解决方案1】:

您的delay 函数使用繁忙循环。这在计算能力方面是不必要的昂贵。在电池供电的设备上这样做是非常不受欢迎的。此外,clock() 不一定返回毫秒数。 clock() 函数使用的单位可以使用CLOCKS_PER_SEC 宏来确定。不幸的是,没有可移植的方法来指定以毫秒表示的延迟,符合 POSIX 的系统有 usleep()nanosleep()

您的行计数功能不正确:您计数了 1 行太多,除非文件结尾没有尾随换行。

这是一个改进的版本:

int countlines(const char *filename) {
    FILE *fp = fopen(filename, "r");
    int ch, last = '\n';
    int lines = 0;

    if (fp != NULL) {
        while ((ch = fgetc(fp)) != EOF) {
            if (ch == '\n')
                lines++;
            last = ch;
        }
        fclose(fp);
        if (last != '\n')
            lines++;
    }
    return lines;
}

main() 函数也存在问题:

  • 您没有验证命令行上传递了足够多的参数。
  • 您没有在主阅读循环中检查EOF
  • 直到文件结束,您才循环重复该过程,甚至在阅读指定的行数后您也不会问问题how many line(s) do you want to read?...

【讨论】:

  • 是的,你是对的,但我不擅长 c 及其库。我不能这样做,我如何索引最后一行并从那里继续前进
  • @f.koglu:对不起,我不明白你的评论。
  • 例如程序我运行程序并且程序写了 5 行。然后问我要读多少行我写 8. 我怎样才能从第六行开始?我必须放一个循环?你能写这个循环吗?
  • @f.koglu: 在你读完这 5 行之后,用printf()scanf() 询问用户输入,然后继续阅读输入的行数......然后把它放进去循环重复,直到到达文件末尾。我自己写不出完整的作业,你自己想办法。
  • 是的,我知道这种算法类型,但我无法将其放入代码中
【解决方案2】:

首先,如果找不到文件,countlines 方法返回零。您应该使用该值来编写错误消息,并跳过其余代码。

其次,在下一个循环中,你使用

    if (ch != '\n') {
        printf("%c", ch);
    } else {
        printf("\n");
        delay(s2);
        x++;
    }

为什么有两个 printf 语句?他们会打印同样的东西。 也许是这样的:

 ch = getc(ptDosya);
 /* exit the loop here if you hit EOF */

 printf("%c", ch);  /* Why not putc() or putchar()  ? */
 if (ch == '\n') {
    x++;
    if ( x == lineCount ) {
       x = 0;
       lineCount = requestNumberOfLinesToRead();
    } else {
      sleep(s2); /* instead of delay(). Remember to #include unistd.h */
    }
 }

【讨论】:

  • 你明白我的问题吗?你能写下我的代码的缺失部分吗?
猜你喜欢
  • 1970-01-01
  • 2020-02-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-22
  • 2021-11-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多