简体   繁体   English

无法在 C 中打印全部内容

[英]Can't print whole content in C

Got a huge problem.遇到了很大的问题。 Let's say, that I have pointer to a large string (~1500 characters) and I want to print it.假设我有一个指向大字符串(~1500 个字符)的指针,我想打印它。 What I get in the result is only a part of that string.我在结果中得到的只是该字符串的一部分。 After the program prints that part it asks me for a newline.程序打印该部分后,它要求我换行。 After I press enter the program prints the rest of the string and terminates.按回车键后,程序打印字符串的其余部分并终止。 It happens when I try to run my program in terminal or with IDE.当我尝试在终端或 IDE 中运行我的程序时会发生这种情况。 If I try to debug it, it works perfectly.如果我尝试调试它,它可以完美运行。 I need it to print whole string without terminating the program.我需要它在不终止程序的情况下打印整个字符串。 So, here's the code (there's lots of mistakes in the code):所以,这是代码(代码中有很多错误):

#include<stdio.h>
#include<sys/socket.h>
#include<sys/types.h>
#include<netdb.h>
#include<string.h>

#define SOCKET int        // Apibreziame sinonima 'int' tipui, kad butu
                          // unix ir WIN sistemoms bendras kodas dirbant
                          // su soketu deskriptoriais.
#define closesocket close // Apibreziame sinonima close () funkcijai
                          // closesocket (), kuris yra analogas Windows
                          // tipo sistemose. Tai del kodo suvienodinimo.
#define INVALID_SOCKET -1 // Apibreziame del kodo suvienodinimo, klaidos
#define SOCKET_ERROR -1   // situacijai nusakyti konstantas, kurios WINSOCK'o

#define MAX_CH 255
#define POP3_PORT 110
#define MAXLEN 1024

int main()
{
    SOCKET socketE;
    struct sockaddr_in servaddr;
    struct hostent* h = NULL;

    char* Packet = NULL;

    Packet = (char*)malloc(MAX_CH);
    memset(Packet, 0, sizeof(Packet));

    printf("POP3 server: ");
    gets(Packet);

    /*******{ 
    client connects to the mail server and other stuff
    server sends greeting message
    client receives greeting message 
    }*******/

    if (!strstr(Packet,"+OK")) {
        print_error(Packet);
    }
    else {
        printf("%s", Packet);
        int printedData = 0;
        while (1) {
            Packet = (char*)realloc(NULL, 1);
            memset(Packet, 0, sizeof(Packet));
            gets(Packet);
            strcat(Packet, "\n");
            if (SOCKET_ERROR == SendPacket(&socketE, Packet)) {
                print_error("Error on sending data to mail server.\n");
            }
            memset(Packet, '\0', sizeof(Packet));
            if (SOCKET_ERROR == ReceivePacket(&socketE, &Packet)) {
                print_error("Error on receiving data from mail server.\n");
            }
            if (!strstr(Packet,"+OK")) {
                fwrite(Packet, 1, strlen(Packet), stdout);
                break;
            }
            printf("%s", Packet);  //THIS IS WHERE THE PRINT PART COMES
        }
    }
    close(socketE);
    return 0;
}

Okey, so I have found out that this if clause (I mean, even if this if is false) stops program from printing all the content.好吧,所以我发现这个 if 子句(我的意思是,即使这个 if 是假的)会阻止程序打印所有内容。 If I remove/comment it, I got my program working correctly.如果我删除/评论它,我的程序就可以正常工作了。 Is it possible, that this one causes all the problems?有没有可能,这会导致所有问题?

if (!strstr(Packet,"+OK")) {
    fwrite(Packet, 1, strlen(Packet), stdout);
    break;
}

This:这个:

Packet = (char*)realloc(NULL, 1);
memset(Packet, 0, sizeof(Packet));

causes undefined behavior.导致未定义的行为。 It allocates a single byte (why would you ever do this?) and then clears sizeof(Packet) bytes, which on most typical systems today is either 4 or 8 bytes.它分配一个字节(你为什么要这样做?)然后清除sizeof(Packet)字节,在当今大多数典型系统上,它是 4 或 8 个字节。 Thus, it writes outside the allocated memory.因此,它写入分配的内存之外。 Note that sizeof cannot track dynamic allocations, so this whole pattern is wrong.请注意, sizeof无法跟踪动态分配,因此整个模式是错误的。

Also, please note that dynamic memory allocation can fail ;另外,请注意动态内存分配可能会失败 you must check the return value of every call to realloc() before relying on the returned pointer being valid.在依赖返回的指针有效之前,您必须检查每次调用realloc()的返回值。 If it's NULL , you can't access through it.如果它是NULL ,则无法通过它访问。

Further, just like with malloc() , please don't cast the return value of realloc() in C.此外,就像malloc()请不要在 C中转换realloc()的返回值

Try to add flush after printf :尝试在printf之后添加 flush :

printf("%s", Packet);
fflush(stdout);

printf use stdout , which is line buffered. printf使用stdout ,它是行缓冲的。 So printf texts can be partly flushed (printed) if there is no '\\n' in the end of the string.因此,如果字符串末尾没有'\\n' ,则可以部分刷新(打印) printf文本。

In your case unflushed text is flushed when you type the newline.在您的情况下,当您键入换行符时,未刷新的文本会被刷新。

Stdout is line buffered and characters in the stdout stream are saved until a newline is output or input is read from any stream attached to a terminal device, or if the stream buffer gets full.标准输出是行缓冲的,标准输出流中的字符将被保存,直到输出换行符或从连接到终端设备的任何流中读取输入,或者如果流缓冲区已满。 so you may either put the '\\n' character in your printf like printf("%s\\n",Packet);所以你可以把 '\\n' 字符放在你的 printf 中,比如 printf("%s\\n",Packet); or just disable the stdout buffering using setbuf(stdout, NULL);或者只是使用 setbuf(stdout, NULL) 禁用标准输出缓冲; for printf to print the complete string printf 打印完整的字符串

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

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