简体   繁体   中英

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. 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. 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 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. Thus, it writes outside the allocated memory. Note that sizeof cannot track dynamic allocations, so this whole pattern is wrong.

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. If it's NULL , you can't access through it.

Further, just like with malloc() , please don't cast the return value of realloc() in C.

Try to add flush after printf :

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

printf use stdout , which is line buffered. So printf texts can be partly flushed (printed) if there is no '\\n' in the end of the string.

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); or just disable the stdout buffering using setbuf(stdout, NULL); for printf to print the complete string

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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