Jump to content

Hi,

 

I am writing a C program that will take a certain number of characters (a word), print them backwards, and then tell the user whether or not the word is a palindrome. I ran into trouble with the scanf() function when trying to scan user input to a char variable after previously scanning into an int variable. After a quick Google search, I found out the problem was that I was not putting a space before the %c in my scanf function. But even after I put the space, the program would still loop infinitely, and I'm not sure whether it is a problem with my recursive string function or the scanf function I am using. Here is the code:

 

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

main()
{
    int getString();
    int maxChar;

    printf("Maximum number of characters for this run? ");
    scanf("%d", &maxChar);

    printf("\nEnter no more than %d characters: ", maxChar);
    getString();
    printf("\n");
}

int getString()
{
    char c;
    scanf(" %c", &c);

    if(c != '\n')
    {
        getString();
        printf("%c", c);
    }
}

As this is a homework assignment for a C class, I am not allowed to use strlen() or any other special functions. I can only use functions that I define myself (besides basic ones like printf() and scanf()). The program I have right now will take a string that the user enters and print it backwards, but only if I get rid of the scanf for the maxChar variable. Here is what the normal output looks like when it is working properly:

image.png.ffa2aa7446502247a355186e446a8de0.png

And here it is with the new scanf function:

image.png.db7f4b04bf10115f3c7b0bf98d9147e0.png

The program will get hung here, I assume looping infinitely for some reason. If i remove the space in front of the %c in the getString() funciton, the program will crash after the max characters input like so:

image.png.d86d88bf8b0ea5e2851c9f20711bfe17.png

I assume this is not a crash but rather the program finishing after the scanf function in the getString() function reads the whitespace from the previous scanf and then cancels the if statement and prints nothing, terminating the program.

 

I am not sure how to get around this, as we are not supposed to keep the main function relatively empty and use our own defined functions to scan user input.

 

EDIT: I've been messing around with the program a bit just trying to get an external function which can read user input and then store it in the string array, however I have been getting a segmentation fault when I run the program. Here is the code:

#include <stdio.h>

main()
{
    int getString(int maxCharacters, char characterArray[100]);
    int reverse();
    int isPalindrome();

    int maxCharacters = 0;
    char characterArray[100];

    char programLoop = 'y';

    do
    {
        printf("Maximum number of characters for this run?\n");
        scanf("%d", & maxCharacters);

        printf("The maximum number of characters is %d\n", maxCharacters);

        getString(maxCharacters, characterArray);

        printf("Run the program again? (y/n)\n");
        scanf(" %c", &programLoop);

    } while(programLoop == 'y');
}

int getString(int maxCharacters, char characterArray[100])
{
    printf("    Enter no more than %d characters: ", maxCharacters);
    scanf(" %s", &characterArray);
    printf("%s\n", characterArray);
}

The result looks like this:

image.png.bff1d92f17b2edd3d78cc477bd979e5f.png

I feel like its a problem in a way I am passing the characterArray array as an argument for the getString() function, but I'm not sure what I am doing wrong...

 

Any advice would be greatly appreciated,

 

Thanks!

Edited by SgtBot
Additional problems
Link to comment
https://linustechtips.com/topic/988703-scanf-function-help-in-c/
Share on other sites

Link to post
Share on other sites

So you can't actually pass an array as a value in C/C++ (you can pass structs and classes as values, but arrays are not those things). When you take in an array as a function parameter, you are actually passing the pointer to the location in memory of the first element in said array.

 

So your function declaration here

int getString(int maxCharacters, char characterArray[100])

is actually identical to

int getString(int maxCharacters, char *characterArray)

so when you try to get the address with

scanf(" %s", &characterArray);

you are attempting to tell scanf to put the user input into the address of where the pointer to where characterArray is stored on the stack, not where your characterArray is stored. In other words, you're one address too deep. Just remove the & and this should work fine.

 

The reason you were getting a segfault was because scanf was trying to write your char * to the char * * at location &characterArray.

Gaming build:

CPU: i7-7700k (5.0ghz, 1.312v)

GPU(s): Asus Strix 1080ti OC (~2063mhz)

Memory: 32GB (4x8) DDR4 G.Skill TridentZ RGB 3000mhz

Motherboard: Asus Prime z270-AR

PSU: Seasonic Prime Titanium 850W

Cooler: Custom water loop (420mm rad + 360mm rad)

Case: Be quiet! Dark base pro 900 (silver)
Primary storage: Samsung 960 evo m.2 SSD (500gb)

Secondary storage: Samsung 850 evo SSD (250gb)

 

Server build:

OS: Ubuntu server 16.04 LTS (though will probably upgrade to 17.04 for better ryzen support)

CPU: Ryzen R7 1700x

Memory: Ballistix Sport LT 16GB

Motherboard: Asrock B350 m4 pro

PSU: Corsair CX550M

Cooler: Cooler master hyper 212 evo

Storage: 2TB WD Red x1, 128gb OCZ SSD for OS

Case: HAF 932 adv

 

Link to post
Share on other sites

I see it now, I was trying to write the user input to the pointer, when I should have been writing to the variable that the pointer was pointing to, right?

 

I think I fixed the code, and I added another function to print out the word backwards, but I'm not sure if I'm correctly understanding how to use the pointer in this function either.

 

Here's the code:

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

main()
{
    int getString(char *characterArray);
    void reverse(int charCount, char *characterArray);

    int charCount = 0;

    char characterArray[100]; /* Max buffer size for the array is 100 */
    int maxChar;

    printf("Maximum number of characters for this run? ");
    scanf("%d", &maxChar);

    printf("\n    Enter no more than %d characters: ", maxChar);
    charCount = getString(characterArray)-1;
    printf("\n    You entered %d characters.\n", charCount);

    reverse(charCount, characterArray);
}

int getString(char *characterArray)
{
    int charCount = 0;

    scanf(" %s%n", characterArray, &charCount);

    return charCount;
}

void reverse(int charCount, char *characterArray)
{
    int i;

    for(i = charCount - 1; i < 0; i--)
        printf("%s", &characterArray[i]);
}

This code is printing out:

image.png.21d5ccc1fc8d86b8332d767ea7c1ecf3.png

it seems to start on the right side but starts spamming out random letters from the string that shouldn't be printing out. I'm not sure why its doing this unless it is a 2 dimensional array with multiple string arrays in the array.

Link to post
Share on other sites

11 hours ago, SgtBot said:

 


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

main()
{
    int getString(char *characterArray);
    void reverse(int charCount, char *characterArray);

 

Generally, one does not put function prototypes inside another function. Looks like something from ancient K&R to me.

Common practice is to put them in the top of the file (or put the functions themselves before main, then you no longer need prototypes).

11 hours ago, SgtBot said:

void reverse(int charCount, char *characterArray)
{
    int i;

    for(i = charCount - 1; i < 0; i--)
        printf("%s", &characterArray[i]);
}

 

 

First, the loop condition is wrong. You want to count backwards from charCount - 1 upto, and including, 0. So the condition should be i >= 0.

Secondly, format specifier %s tells printf to print an entire string until it finds a 0-terminator. Printing a single character is done with format specifier %c.

Thirdly, you're asking printf to print a memory address rather then want that address holds:

characterArray[i] dereferences index element 'i' from the characterArray. Thus this returns the actual element...
& takes the memory address of a element...
  
so &characterArray[i] gives you the memory address of the element at index i inside the characterArray. 

So, your reverse function should be:

void reverse(int charCount, char *characterArray)
{
    	int i;

	for (i = charCount - 1; i >= 0; --i)
   	{
		printf("%c", characterArray[i]);
	}
}

 

Note that scanf is considered unsafe - you cannot limit how many characters it should read and thus can overflow the buffer -  and thus should not be used in actual software.

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

×