Jump to content

This program is designed to count how many vowels are in the words the user input, and the program ends when the user does CNTR+D. For some reason the last time the loop runs it always adds the last found vowel a second time.

 

So you would enter 'a' and it would say there were 2 of them.

 

#include <stdio.h>
#include <string.h>

int main(){
    
    // Creates string variable to store the users input
    char userString[64];

    // Prompts user for a string
    printf("Please enter a string that is all lowercase and less than 50 charecters\n");

    // Creates variables to store the number of each vowel in the string
    int numA = 0;
    int numE = 0;
    int numI = 0;
    int numO = 0;
    int numU = 0;

    // While loop to count how many of each vowel(s) are in the lowercase string
    while(1) {

        // Ends the program when the user enters CTRL+D
        if (feof(stdin)) break;

        // Stores the user input in userString
        scanf("%s", userString);

        for (int i = 0; userString[i] != '\0'; i++) {
            // Adds the 1 to the total number of each vowel when the vowel comes up in the string
            if (userString[i] == 'a') {
                numA += 1;
            }
            else if (userString[i] == 'e') {
                numE += 1;
            }
            else if (userString[i] == 'i') {
                numI += 1;
            }
            else if (userString[i] == 'o') {
                numO += 1;
            }
            else if (userString[i] == 'u') {
                numU += 1;
            }
        }
    }

    // Prints the output for the number of each vowel in the string
    printf("The vowel a occurred %d times\n", numA);
    printf("The vowel e occurred %d times\n", numE);
    printf("The vowel i occurred %d times\n", numI);
    printf("The vowel o occurred %d times\n", numO);
    printf("The vowel u occurred %d times\n", numU);

    // Returns a 0 to end the program
    return 0;
}

 

Link to comment
https://linustechtips.com/topic/1375002-weird-behavior-in-c-for-loop/
Share on other sites

Link to post
Share on other sites

47 minutes ago, jrhaberland said:

This program is designed to count how many vowels are in the words the user input, and the program ends when the user does CNTR+D. For some reason the last time the loop runs it always adds the last found vowel a second time.

 

So you would enter 'a' and it would say there were 2 of them.

I'm not super well versed in some of the C stdio functions, but if you flip the positions of the ctrl-D check and parsing for text, it will return the correct values (per my simulations).

 

EDIT: Here's what I assume is happening in the loop...

  1. Ctrl-D is checked for
  2. String is parsed
  3. String is counted

However, by the time you can enter ctrl-D, the program is already blocking on the "string is parsed" line, so it has to loop through again before the ctrl-D check, and I assume that a ctrl-D input to the parse function doesn't fully overwrite what was in the buffer, so (most of?) it gets counted again. If you do it the other way around (as I suggest), you parse input, then check if it happens to be ctrl-D before continuing to count.

Main System (Byarlant): Ryzen 9 5950X | Asus B550-Creator ProArt | EK 240mm Basic AIO | 32GB G.Skill DDR4 3600MT/s CL16 | XFX Speedster SWFT 210 RX 6600 | Samsung 990 PRO 2TB / Samsung 990 EVO Plus 4TB | Corsair RM750X | StarTech 4× USB 3.0 Card | Realtek RTL8127 10G NIC | Hyte Y60 Case | Dell U3415W Monitor | Keychron K12 Blue (RGB backlight)

 

Laptop (Narrative): Lenovo Flex 5 81X20005US | Ryzen 5 4500U | 16GB DDR4 3200MT/s (soldered) | Vega II 384SP Graphics | SKHynix P31 1TB NVMe SSD | Intel AX200 Wifi | Asus 2.5G USB NIC | Asus ProArt PA278QV | Keychron K4 Brown (white backlight)

 

Proxmox Server (Veda): Ryzen 7 3800XT | ASRock Rack X470D4U | Corsair H80i v2 | 128GB Micron DDR4 ECC 3200MT/s | 2× Samsung PM963a 960GB SSD / 4× WD 10TB / 4× Seagate 14TB Exos / 4× Micron MX500 2TB / 8× WD 12TB (custom external SAS enclosure) | Seasonic Prime Fanless 500W | Intel X550-T2 10G NIC | LSI 9300-8i HBA | Adaptec 82885T SAS Expander | Fractal Design Node 804 Case

 

Proxmox Server (La Vie en Rose)GMKtec Mini PC | Ryzen 7 5700U | 32GB Lexar DDR4 (SODIMM) | Vega II 512SP Graphics | Lexar 1TB 610 Pro SSD | 2× Realtek 8125 2.5G NICs


Media Center/Video Capture (Jesta Cannon): Ryzen 5 1600X | ASRock B450M Pro4 R2.0 | Noctua NH-L12S | 16GB Crucial DDR4 3200MT/s | EVGA GTX750Ti SC | UMIS NVMe SSD 256GB / TEAMGROUP MS30 1TB | Corsair CX450M | Viewcast Osprey 260e Video Capture | TrendNet (AQC107) 10G NIC | LG WH14NS40 BD-ROM | Silverstone Sugo SG-11 Case | Sony XR65A80K

 

Workbench (Doven Wolf): Lenovo m715q | Ryzen Pro 3 2200GE | 16GB Crucial DDR4 3200MT/s (SODIMM) | Vega 8 Graphics | SKHynix (OEM) 256GB NVMe SSD | uni 2.5G USB NIC | HDMI add-in module

 

Network:

Spoiler
                       ┌─────────────── Office/Rack ───────────────────────────────────────────────┐
Google Fiber Webpass ── Cloud Gateway Max ══╦═ Pro XG 8 ══╦═ Flex 2.5-8 ══╦═ Doven Wolf
                      La Vie en Rose (DNS) ═╬═ Narrative  ╠═ Veda-NAS     ╠═ La Vie en Rose (vmbr)
                                Veda (DNS) ─┘             ╠═ Veda (vmbr)  ├─ Ptolemy (vmbr)
╔═════════════════════════════════════════════════════════╩═ Ptolemy-NAS  ├─ Veda (Mgmt)
║   ┌ Closet ┐      ┌───────── Bedroom ─────────┐                         └─ Veda (IPMI)
╚═══ Flex XG ══╦╤═══ Flex XG ══╤╦═ Byarlant
       (PoE)   ║│              │╠═ Narrative 
Kitchen Jack ══╣└─ Dual PoE ┐  │╚═ Jesta Cannon*
   (Testing)   ║┌─ Injector ┘  └── Work Laptop
     Bedroom ══╝│        ┌─────── Media Center ────────────────────────────┐
     Jack #2    └──────── Switch 8 ────────────┬─ nanoHD Access Point (PoE)
Notes:                                         ├─ Sony PlayStation 4 
─── is Gigabit / ═══ is Multi-Gigabit          ├─ Pioneer VSX-S520
* = cable passed from Bedroom to Media Center  └─ Sony XR65A80K (Google TV)
Link to post
Share on other sites

11 minutes ago, AbydosOne said:

However, by the time you can enter ctrl-D, the program is already on the "string is parsed" line, so it has to loop through again before the ctrl-D check,

Precisely this. At the beginning of loop #2, the EOF check fails, and scanf() gets called. scanf() encounters EOF, and returns without doing anything to userString. The loop continues, and parses userString again. At the beginning of loop #3, the EOF check passes, and the while loop breaks.

 

Instead of a while(true) loop, this should be the conditional check:

while(scanf("%s", userString) != EOF)

 

Link to post
Share on other sites

I was able to fix it by doing this

    // While loop to count how many of each vowel(s) are in the lowercase string
    while(1) {

        // Stores the user input in userString
        scanf("%s", userString);

        // Ends the program when the user enters CTRL+D
        if (feof(stdin)) {
            break;
        }

Essentially just had to switch it so the scanf is before the feof(stdin) statement.

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×