Hack Forums
[Help] Help with C input handling - Printable Version

+- Hack Forums (https://hackforums.net)
+-- Forum: Tech (https://hackforums.net/forumdisplay.php?fid=444)
+--- Forum: Coding (https://hackforums.net/forumdisplay.php?fid=151)
+---- Forum: Coders Lounge (https://hackforums.net/forumdisplay.php?fid=5)
+---- Thread: [Help] Help with C input handling (/showthread.php?tid=6288659)



Help with C input handling - TomDH - Jan 2, 2025

hey, I'm writing a C program that simulates a "low cost" spotify, only storing names, artists, lyrics, and streams in the program
the code works fine
but there's one key issue
if I enter the input in cmd line by line, it works perfectly
if I take the input from a file, it works perfectly
but if I paste it all at the same time, it won't register the last input unless there's a whitespace after it

this is my main loop:
Code
int main() {
    Playlist **playlists = NULL;
    int playlistCount = 0;
    int choice = 0;
    do{
        printMainMenu();
        scanf("%d", &choice);
            switch (choice) {
                case 4:
                {
                    break;
                }
                case 1:
                {
                    showPlaylists(playlists, playlistCount);
                    break;
                }
                case 2:
                {
                    addPlaylist(&playlists, &playlistCount);
                    break;
                }
                case 3:
                {
                    deletePlaylist(&playlists, &playlistCount);
                    break;
                }
            }
    }while(choice != 4);
    for (int i = 0; i < playlistCount; i++) {
        freePlaylist(playlists[i]);
    }
    free(playlists);
    printf("Goodbye!\n");
    return 0;
}

and in the functions themselves I do not clear the buffer unless after I get a scanf to get a choice in inner-menus
when I try to get the input with getchar() instead of scanf it just breaks the code entirely and removes first characters from longer inputs in the future, and prints the menu twice sometimes.
would appreciate some help on how to get the last input even when it isn't followed by a whitespace



TLDR : pasting multiple lines of input into cmd and it stalls when input doesn't end with whitespace

Thanks in advance to anyone helping out!


RE: Help with C input handling - Bastille - Jan 2, 2025

Hello, I'm not into programming but this is what I've got with ChatGPT, could you try ?


AI Quote:
The issue you're facing is due to how scanf interacts with the input buffer. When you paste multiple lines into the terminal, scanf can leave a newline (\n) or other characters in the input buffer. This often results in the last input being unprocessed if not followed by a whitespace or newline, especially when using scanf("%d", &choice).

Here's how you can fix or mitigate the issue:
Key Points:

  • Flushing the Input Buffer: After every scanf, you should clear the remaining characters in the buffer to ensure the program doesn't hang or behave unexpectedly.

  • Using fgets Instead of scanf: fgets is safer for handling input as it reads the entire line, making it less likely to leave stray characters in the input buffer.



Updated Main Loop with Buffer Management:

Replace your scanf("%d", &choice) with a safer approach:

Code
#include <stdio.h>
#include <stdlib.h>

int main() {
    Playlist **playlists = NULL;
    int playlistCount = 0;
    int choice = 0;
    char buffer[100]; // Buffer to read input as a string
    
    do {
        printMainMenu();
        if (fgets(buffer, sizeof(buffer), stdin) != NULL) {
            // Convert input string to integer
            if (sscanf(buffer, "%d", &choice) != 1) {
                printf("Invalid input. Please enter a number.\n");
                continue;
            }
        } else {
            printf("Error reading input.\n");
            break;
        }

        switch (choice) {
            case 4:
                break;
            case 1:
                showPlaylists(playlists, playlistCount);
                break;
            case 2:
                addPlaylist(&playlists, &playlistCount);
                break;
            case 3:
                deletePlaylist(&playlists, &playlistCount);
                break;
            default:
                printf("Invalid choice. Please try again.\n");
        }
    } while (choice != 4);

    for (int i = 0; i < playlistCount; i++) {
        freePlaylist(playlists[i]);
    }
    free(playlists);
    printf("Goodbye!\n");
    return 0;
}

Why This Works:

fgets Reads Entire Line: Ensures that any leftover newline characters are included in the input, preventing issues when pasting multiple lines of input.
sscanf for Parsing: Safely converts the input string into an integer while avoiding issues caused by stray characters in the buffer.
Buffer Size: Use a sufficiently large buffer (char buffer[100]) to handle user input, but ensure it aligns with your maximum expected input size.

Notes:

Menu Loop Safety: Adding clear prompts and handling invalid inputs ensures your program doesn’t break when unexpected input is given.
Test Edge Cases: Paste inputs with trailing newlines, without trailing spaces, or even with invalid characters to verify robustness.








RE: Help with C input handling - HFDone - Jan 2, 2025

so put check for the last line


RE: Help with C input handling - Phobia_ - Jan 3, 2025

Couldn’t this be done more easily with Spotify API?