简体   繁体   English

小C程序不起作用

[英]small C program doesnt work

I tried to make a program that gets a user input(lines) and prints the longest line that is over 80 characters long. 我试图制作一个程序来获取用户输入(行),并打印出超过80个字符的最长行。 I made the program , but when i ran it , it outputed some very weird symbols. 我编写了程序,但是运行它时,它输出了一些非常奇怪的符号。 Could you please tell me what might be wrong with my code ? 您能告诉我我的代码可能出什么问题吗?

#include <stdio.h>
#define MINLINE 80
#define MAXLINE 1000

int getline(char current[]);
void copy(char from[], char to[]);

int main(void)
{
    int len; // current input line lenght
    int max; // the lenght of a longest line that's over 80 characters
    char current[MAXLINE]; // current input line
    char over80[MAXLINE]; // input line that's over 80 characters long

    while (len = (getline(current)) > 0) {
        if (len > MINLINE) {
            max = len;
            copy(current, over80);
        }
    }

    if (max > 0) {
        printf("%s", over80);
    }
    else {
        printf("No input line was over 80 characters long");
    }

    return 0;
}

int getline(char current[]) {
    int i = 0, c;
    while (((c = getchar()) != EOF) && c != '\n') {
        current[i] = c;
        ++i;
    }

    if (i == '\n') {
        current[i] = c;
        ++i;
    }

    current[i] = '\0';

    return i;
}

void copy(char from[], char to[]) {
    int i = 0;
    while ((to[i] = from[i]) != '\0') {
        ++i;
    }
}

Thank you very much for your help ! 非常感谢您的帮助 !

max can be not initialized if no long line is found. 如果找不到长行,则无法初始化max Using it in if (max > 0) is then undefined behavior. 然后在if (max > 0)使用它是未定义的行为。

This line: 这行:

  while (len = (getline(current)) > 0) {

assigns the value of (getline(current)) > 0) to len , which is not what you want (len will be 0 or 1 afterwards. (getline(current)) > 0)的值分配给len ,这不是您想要的(之后len将为0或1。

EDIT: Just saw AusCBloke's comment, you should also check for both len > max and len > MINLINE or you'll just get the latest line longer than 80 chars, not the longest overall line. 编辑:刚看到AusCBloke的评论,您还应该同时检查len > max len > MINLINE否则您将得到的最新len > MINLINE于80个字符,而不是最长的len > MINLINE

You should also initialize max to 0, so it should be 您还应该将max初始化为0,因此应为

  max = 0;
  while ((len = getline(current)) > 0) {
    if ((len > MINLINE) && (len > max)) {

Other minor errors/tips: 其他小错误/提示:

  • The built in functions strcpy and strncpy do what your copy function does, there's no need to reinvent the wheel. 内置函数strcpystrncpy执行copy功能,而无需重新设计轮子。
  • In your getline function, use MAXLINE to prevent buffer overflows. 在您的getline函数中,使用MAXLINE防止缓冲区溢出。

Assuming that this is a homework, here's a hint: this piece of code looks very suspicious: 假设这是一项家庭作业,这是一个提示:这段代码看起来非常可疑:

if (i == '\n') {
    current[i] = c;
    ++i;
}

Since i represents a position and is never assigned a character, you are effectively checking if the position is equal to the ASCII code of '\\n' . 由于i代表一个位置并且从未分配过字符,因此您可以有效地检查该位置是否等于ASCII代码'\\n'

Your copy method doesn't null terminate the string: 您的复制方法不能为null终止字符串:

void copy(char from[], char to[]) {
    int i = 0;
    while ((to[i] = from[i]) != '\0') {
        ++i;
    }
    to[i] = '\0'
}

which probably explains the weird characters being printed. 这可能解释了正在打印的怪异字符。

You could use the builtin strcpy() to make life easier. 您可以使用内置的strcpy()使生活更轻松。

If you supply input data that has lines with more than 1000 characters you will overflow your fixed size buffers. 如果您提供的输入数据行数超过1000个字符,则固定大小的缓冲区将溢出。 By feeding in such input I was able to achieve the following output: 通过输入这样的输入,我可以实现以下输出:

╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠ ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠ ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠ ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠ ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠ ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠ ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠ ╠╠╠╠╠╠╠╠╠╠╠╠ ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠ ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠

I can't test your code right now, but it may be caused by character arrays not being cleaned. 我目前无法测试您的代码,但这可能是由于未清除字符数组引起的。 Try memset-ing the char arrays to 0. 尝试将char数组设置为0。

There are a number of problems with your code. 您的代码有很多问题。 Mostly they are due to wheel-reinvention. 大多数情况下,这是由于车轮的重新发明。

int getline(char current[]);

You don't need to define your own, getline() , there is already one in stdio.h . 您不需要定义自己的getline()stdio.h已经有一个。

void copy(char from[], char to[]);

There are also a number of functions for copying strings in string.h . 还有许多用于在string.h复制字符串的函数。

It's also a good idea to initialise all 0f your variables, like this: 初始化所有0f变量也是一个好主意,如下所示:

    int len = 0; // current input line length

...this can prevent problems later, like comparisons to max when you haven't initialised it. ...这可以防止以后出现问题,例如在未初始化时与max进行比较。

If you initialise max like this... 如果您这样初始化max ...

    int max = MINLINE; // the length of a longest line that's over 80 characters

...then it's easier to do the length comparison later on. ...然后,以后进行长度比较会更容易。

    char* current = NULL;
    size_t allocated = 0;

If current is NULL , then getline() will allocate a buffer for storing the line, which should be free d by the user program. 如果currentNULL ,则getline()将分配用于存储行的缓冲区,该缓冲区应由用户程序free getline() also takes a pointer to a size_t , which contains the amount of bytes needed to store the line. getline()还使用一个指向size_t的指针,该指针包含存储行所需的字节数。

    while (len = (getline(current)) > 0) {

Should be replaced by the following... 应该由以下内容代替...

    while ((len = getline(&current, &allocated, stdin)) > 0) {

...which updates and compares len to 0 . ...更新并比较len0

Now, instead of... 现在,而不是...

        if (len > MINLINE) {

...you need to compare with the last longest line, which we initialised earlier... ...您需要与我们早先初始化的最后最长线进行比较...

        if (len > max) {

...and then you're good to update max as you were... ...然后您就可以像以前那样更新max ...

            max = len;

Where you called your copy() use strncpy() , which will prevent you writing over 1,000 characters into the allocated buffer: 在调用copy()使用strncpy() ,这将防止您在分配的缓冲区中写入超过1,000个字符:

            strncpy(over80, current, MAXLINE);

Because we initialised max , you'll need to change your check at the end from if (max > 0) to if (max > MINLINE) . 由于我们初始化了max ,因此您需要在末尾将检查从if (max > 0)更改为if (max > MINLINE)

One more tip, changing the following line... 另一个提示,更改以下行...

        printf("No input line was over 80 characters long");

...to... ...至...

        printf("No input line was over %d characters long", MINLINE);

...will mean that you only have to change the #define at the top of the file to increase or decrease the minimum length. ...将意味着您只需要更改文件顶部的#define即可增加或减少最小长度。

Don't forget to... 别忘了...

    free(current);

...to prevent memory leaks! ...以防止内存泄漏!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM