Shuffle a string input by user - c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char rand(char x);
int main()
{
char input[80] = {0};
char rando[80] = {0};
char choice = 0;
char rando2[80] = {0};
if(strlen(input) >= 10 && strlen(input) <= 80); {
printf("Please enter a string with 10-80 characters: ");
scanf("%s", input);
printf("Orginal string: %s\n", input);
rando = my_rand(input);
printf("New string: %s\n", rando); }
else{
return 0; }
printf("Would you like to shuffle this string again?(y or n): ");
scanf("%c\n", &choice);
if( choice == 'y') {
rando2 = my_rand(rando);
printf("New string: %s\n", rando2);
}
else if {
printf("Would you like to shuffle another string?(y or n): ");
scanf("%c\n", &choice2); }
if(choice2 == 'y') {
printf("Please enter a string with 10-80 characters: ");
scanf("%s", input2);
printf("Original string: %s\n", input2);
char rando3 = my_rand(rando2);
printf("New string: %s\n", rando3); }
else:
return 0;
return 0;
}
Hello guys, my goal is to shuffle a user input string as many times as they would like, prompting whether to keep going or not. I am have a tough time figuring out how to shuffle the string, can anyone lend a hand?
This is the sample output:
Please enter a string with 10-80 characters:
initialnaivepassword
Original string: initialnaivepassword
New string: ntlvdiepnaaorsiiiwas
Would you like to shuffle this string again:y
New string: saiiwndrvpaiioneslat
Would you like to shuffle this string again:n
Would you like to shuffle another string? :y
Please enter a string with 10-80 characters:
anothernaivepassword
Original string: anothernaivepassword
New string: svdoanoprhsterneaaiw
Would you like to shuffle this string again:y
New string: eaapnrtwhrosvidosaen
Would you like to shuffle this string again:n
Would you like to shuffle another string? :n

Here's some code that does the shuffling, hope it's helpful:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
void shuffle(char *);
int main(int argc, char *argv[])
{
char sBuff[1024];
char sFinish[10];
srand(time(NULL));
printf("Enter a string:\n");
scanf("%s",sBuff);
do
{
shuffle(sBuff);
printf("\nShuffled string is:\n%s\n\n",sBuff);
printf("Suffle again? (y/n)\n");
scanf("%s",sFinish);
}
while (strcmp(sFinish,"y") == 0);
return 0;
}
void shuffle(char *sBuff)
{
int i, random, length = strlen(sBuff);
char temp;
for (i = length-1; i > 0; i--)
{
random = rand()%(i+1);
temp = sBuff[random];
sBuff[random] = sBuff[i];
sBuff[i] = temp;
}
}

char choice[1] = ""; //wrong declaration. You should either declare a single character or array with two characters
rando = rand(input); // you are passing string here
so the declaration of function is also wrong
char rand(char x);
if else { // you should use `else if` not `if else`
and you are using function name rand is not good practice as this is predefined function found stdlib.h.
use my_rand

This is not a solution ( but you are most welcome to upvote it :-D ), just a long comment.
Change your
1.
char input[80] = "";
char rando[80] = "";
char choice[1] = "";
char rando2[80] = "";
To
char input[80] = {0}; // Will initialize all 80 char mem to 0
char rando[80] = {0};
char choice = 0; // As you want only one char as input, no need to use an array.
// Just initialize the char to 0
char rando2[80] = {0};
2.
else: // Is not supported in C
To
else {/* code here*/}
3.
scanf("%c\n", choice);
if( choice == y)
To
scanf("%c\n", &choice); // choice is no longer an array,
// so we have to pass the address of choice
if( choice == 'y' ) // 'y' is not an int value, its a char literal

Your code is wrong on many levels (as you state already in the fact that it doesn't compile). I'll annotate what I can find:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* useless, you hide a builtin function here, without implementing anything */
char rand(char x);
int main()
{
char input[80] = "";
char rando[80] = "";
char choice[1] = "";
char rando2[80] = "";
/* 1. this is always true, as you have just filled the arrays
* 2. the semicolon after if means there is no body, so the body's scope is always executed
*/
if(strlen(input) >= 10 && strlen(input) <= 80); {
printf("Please enter a string with 10-80 characters: ");
scanf("%s", input);
printf("Orginal string: %s\n", input);
/* input is a char[], rand takes a char */
rando = rand(input);
printf("New string: %s\n", rando); }
/* you are using else as a label here, probably not allowed */
else:
return 0;
printf("Would you like to shuffle this string again?(y or n): ");
scanf("%c\n", choice);
/* y is not declared, so this results in an unknown variable, you probably mean 'y',
* then again, choice is a char[] not a char
*/
if( choice == y) {
rando2 = rand(rando);
printf("New string: %s\n", rando2);
}
/* if else is invalid */
if else {
printf("Would you like to shuffle another string?(y or n): ");
scanf("%c", choice2); }
if(choice2 == y) {
printf("Please enter a string with 10-80 characters: ");
scanf("%s", input2);
printf("Original string: %s\n", input2);
char rando3 = rand(rando2);
printf("New string: %s\n", rando3); }
else:
/* no need to return twice */
return 0;
return 0;
}
As I said in a comment. Walk through some basic C tutorials first, get to know the language and its syntax. Then come back with a compilable piece of code. Good luck!

Related

How can I stop the input when I enter end

got this little problem, I made this code for my task, it should input strings and print it in revese, the loop should end when you enter end, but it doesnt end, I know this is not how you check strings but I don't know how to correct it. Thanks in advance for help.
#include <stdio.h>
#include <stdlib.h>
void reverse(char str[]){
int length;
for(length=strlen(str)-1; length >= 0; length--){
printf("%c",str[length]);
}
}
int main(void){
char str[]="";
while(str != "end"){
printf("\nEnter string: ");
scanf("%s", str);
reverse(str);
}
return 0;
}
you have many problems in your code :
when you write char str[]=""; this is will create a string of size = 1 only which will not accept any string you enter except for only one char , so you should do char str[50]; where 50 is the max expected length of the entered string.
it's not while(str != "end") it's , while(strcmp(str,"end") != 0) as you want to compare the strings itself not addresses
it's better to write scanf("%49s", str); than scanf("%s", str); just to make sure that the entered string will always fit in your array
in this line length = strlen(str)-1; , the strlen function return unsigned long long , so you should typecast that and write length = (int)strlen(str)-1; instead
with this all being said , this is the edited code :
#include <stdio.h>
#include <string.h>
void reverse(char str[]){
int length;
for(length = (int)strlen(str)-1; length >= 0; length--){
printf("%c",str[length]);
}
}
int main(void){
char str[50];
while(strcmp(str,"end") != 0){
printf("\nEnter string: ");
scanf("%49s", str);
reverse(str);
}
return 0;
}
and this is the output:
Enter string:abcd
dcba
Enter string:end
dne
Process finished with exit code 0

How to store a string that the user inputted into a char pointer instead of a char array

I'm trying to build a program with C but I'm having trouble changing a char array into a char pointer and adjusting the program accordingly. Here's my current code that I want to change:
#include <stdio.h>
#include <string.h>
#include <unistd.h>
char username[20];
char password[20];
char username_input[20];
char password_input[20];
char user_input;
void create_account(char* usrname, char* passwd) {
printf("==================================CREATE BANK ACCOUNT==================================\n");
while(1) {
printf("Enter a username that is less than 20 characters: ");
scanf("%s", usrname);
if (strlen(usrname) <= 20)
break;
printf("That is not less than 20 characters, try again...\n");
sleep(2);
}
while(1) {
printf("Enter a password that is less than 20 characters: ");
scanf("%s", passwd);
if (strlen(passwd) <= 20) {
break;
}
printf("That is not less than 20 characters, try again... \n");
sleep(2);
}
printf("Thank you, please sign in now...\n");
sleep(2);
}
void login() {
while(1) {
printf("Enter Username: ");
scanf("%s", username_input);
printf("Enter Password: ");
scanf("%s", password_input);
if (strcmp(username, username_input) != 0 || strcmp(password, password_input) != 0) {
printf("Incorrect Username or Password. Try again...\n");
sleep(2);
}
else {
printf("Welcome %s\n", username);
sleep(2);
break;
}
}
}
On the lines at the beginning, you can see that there are 4 char array declarations. I want them to be char pointers like so:
char* username;
char* password;
char* username_input;
char* password_input;
The reason for this is because I don't want a limit in a string, but arrays need limits. Once I change that, I want to use malloc() to allocate memory for what the user inputs but I don't know how. In other words, I want to declare a char pointer that accepts user input. And I want enough memory to be allocated for that pointer so that the string that was inputted has enough space. Also I want my code to be compatible with different compilers and computers. For that I'm pretty sure that I have to multiply the malloc() function with sizeof(char) or something like that. I don't necessarily get an error, as in I don't get red lines in my IDE, but the program stops in the middle of it for no reason and gives me an exit code other than 0.
I have done something like this to alloc memory:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>
void create_account(char** usrname, char** passwd);
void login(char** usrname, char** passwd, char** input_usrname, char** input_passwd);
void AllocMemory(char*** buf);
int main(){
char* username;
char* password;
char* username_input;
char* password_input;
create_account(&username, &password);
login(&username, &password, &username_input, &password_input);
free(username);
free(password);
free(username_input);
free(password_input);
return 0;
}
void create_account(char** usrname, char** passwd) {
printf("==================================CREATE BANK ACCOUNT==================================\n");
printf("Enter a Username: ");
AllocMemory(&usrname);
printf("Enter a Password: ");
AllocMemory(&passwd);
printf("Thank you, please sign in now...\n");
sleep(2);
}
void login(char** usrname, char** passwd, char** input_usrname, char** input_passwd) {
while(1) {
printf("Enter Username: ");
AllocMemory(&input_usrname);
printf("Enter Password: ");
AllocMemory(&input_passwd);
if (strcmp(*usrname, *input_usrname) != 0 || strcmp(*passwd, *input_passwd) != 0) {
printf("Incorrect Username or Password. Try again...\n");
sleep(2);
}
else {
printf("Welcome %s\n", *usrname);
sleep(2);
break;
}
}
}
void AllocMemory(char*** buf){
int bufSize = 10;
int stringSize;
**buf = calloc(bufSize, sizeof(char));
if(**buf == NULL){
printf("[ERROR] can't malloc %d bytes\n", bufSize);
exit(1);
}
char *readpos = **buf; //point to a pointer of your array!
while(1){ //looping until the alocated memory is enough to the inserted command
do{
fgets(readpos, bufSize, stdin); //reads a line from the specified stream
stringSize = strlen(**buf); //getting the size of the array
if (stringSize == 1)
{
printf("\nYou just pressed enter, pls type again: "); //checking if user just pressed enter
}
}while (stringSize == 1); //looping until user press only enter
if (readpos[strlen(readpos)-1] == '\n'){ //Search from the end as there's where the newline should be if exists, the string fits on array and doesnt need to allocate more memory
readpos[strlen(readpos)-1] = '\0'; //Remove \n from the string
break;
}
**buf = realloc(**buf, bufSize + stringSize * sizeof(char)); // Need to allocate more memory, because the before if its false
if(*buf == NULL){
printf("[ERROR] can't realloc more %d bytes\n", bufSize+1);
exit(1);
}
readpos = **buf + stringSize; // Set the pointer to next position to read into
}
}
I dont know if you are using global variables, but this dont have global variables! But if you want you can use them

Counting Number Of User Input in C Program

printf("Enter number of patients:");
int numberOfInputs = scanf("%d", &patients);
if (numberOfInputs != 1) {
printf("ERROR: Wrong number of arguments. Please enter one argument d.\n");
}
I am asking the user to input one number as an argument, but would like to print out a statement if the user does not input anything or puts in more than one input. For example, once prompted with "Enter number of patients:", if the user hits enter without entering anything, I would like to print out a statement. The code above is what I have been specifically tinkering around with it for the past couple hours as a few previous posts on this site have suggested but when I run it in terminal, it does not work. Any suggestions? Thank you in advance, and all advice is greatly appreciated!
If I understand your question right, you want to print an error when the input is anything other than an integer and this includes newline as well. You can do that using a char array and the %[] specifier.
Example:
#include<stdio.h>
#include<stdlib.h>
int main(void)
{
int patients;
char str[10];
printf("Enter number of patients:");
int numberOfInputs = scanf("%[0-9]", str);
if (numberOfInputs != 1) {
printf("ERROR: Wrong number of arguments. Please enter one argument.\n");
}
patients = atoi(str); //This is needed to convert the `str` back to an integer
}
This will print the error when the user just hits ENTER as well.
This looks super over-complicated, but it basically splits the input, checks it to be exactly one and than checks it to be an integer (and converts it). It works fine in loop as well and handles empty input.
I'm sure there are more elegant solutions to this problem, it's just a suggestion.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>
int getNumberOfInput(char* str);
bool isNumber(char* str);
int main()
{
char str[512];
while(1)
{
printf("Enter text: ");
fgets(str, 512, stdin);
int numberOfInput = getNumberOfInput(str);
if ( numberOfInput == 0 )
printf("You must give an input\n");
else if ( numberOfInput > 1 )
printf("You have to give exactly one input\n");
else
{
if (!isNumber(str))
printf("The input is not an integer\n");
else
{
int input = atoi(str);
printf("input: %d\n", input);
}
}
}
return 0;
}
int getNumberOfInput(char* str)
{
char* word = strtok(str, " \t\n\v\f\r");
int counter = 0;
while(word != NULL)
{
++counter;
word = strtok(NULL, " \t\n\v\f\r");
}
return counter;
}
bool isNumber(char* str)
{
int i, len = strlen(str);
for (i=0; i<len; ++i)
if (!isdigit(str[i]))
return false;
return true;
}

C - Segmentation fault when using strlen?

I'm getting a segmentation fault with using strlen.
My function:
void myFunction()
{
int counter = 0;
char * userInput;
bool validInput = true;
while (1)
{
validInput = true;
printf("\nEnter a word: ");
scanf("%s", userInput);
for(counter = 0; counter < strlen(userInput); counter++)
{
if (islower(userInput[counter]) == 0)
{
validInput = false;
break;
}
if (isalpha(userInput[counter]) == 0)
{
validInput = false;
break;
}
}
if (!validInput)
{
printf("Please enter a wordcontaining only lower-case letters.\n");
continue;
}
// Do something
break;
}
}
Is there something wrong with my scanf line? I've never had this sort of issue before with using strlen... so I assume maybe I'm not reading the user's input correctly into 'userInput'.
char * userInput;
The above variable is a pointer , and it is pointing to nowhere (Mean no memory location ) .
It should contain a address to store / retrieve data .
So either you must allocate memory for this variable or use strdup
#include <stdio.h>
#include <stdlib.h>
int main(int argc,char *argv[])
{
char *inputStr; //wrong.
char inputStrArray[100]; //correct
char *inputStrPtr = malloc(sizeof(char)*100) ;//OK but dont forget to free the memory after use
int condition = 1;
while(condition )
{
printf("Please enter a string :");
//scanf("%s",&inputStr); //wrong
//printf(inputStr);
scanf("%s",inputStrArray);
printf("Ok I got it %s \n",inputStrArray);
printf("Please enter one more time a string: ");
scanf("%s",inputStrPtr);
printf("Now I got it %s \n",inputStrPtr);
condition = 0;
}
free(inputStrPtr);
inputStrPtr = NULL; //try not to use it anywhere else
return 0;
}
Use char userInput[128]; instead.
scanf expects a pointer to valid memory to put the contents of the users input in to.

How do I add a contact to a phonebook program in C?

For my intro to programming class, we have to code a phonebook in C that lets users add contacts, as well as delete and display them. It also has to allocate and free memory as necessary (I tried to do this, but I honestly don't really know what I'm doing).
Anyway, I cannot figure out how to add a contact to the phonebook. I've pasted the relevant part of the program so far. It compiles, but it crashes every time I try to add a contact. Once I get this figured out, I think I can get the rest of the functions without too much trouble. If anyone could help me out, I'd really appreciate it.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct entry {
char fname[20];
char lname[20];
char pnumber[20];
} entry;
// function prototypes
void addentry(int, entry*, char addfname[20], char addlname[20], char addpnumber[20]);
main() {
int selection = 0;
int inputtest = 1;
int pnum = 0; // keeps track of number of contacts
char addfname[20] = { '\0' };
char addlname[20] = { '\0' };
char addpnumber[20] = { '\0' };
entry *pcontacts;
pcontacts = (entry*)calloc(1, (sizeof(entry)));
if (pcontacts == NULL) {
printf("No memory is available.");
free(pcontacts);
return 0;
}
while (1) {
do {
printf("\nPhonebook Menu\n\n");
printf("1:\tAdd contact\n");
printf("2:\tDelete contact\n");
printf("3:\tDisplay contacts\n");
printf("4:\tExit\n");
printf("\nChoose an action (1-4): ");
scanf("%d", &selection);
if (selection < 1 || selection > 4) {
printf("Invalid input. Please enter an integer between 1 and 4.\n");
inputtest = 0;
}
if (selection == 4) {
free(pcontacts);
printf("\nThank you for using this phonebook.");
return 0;
}
switch (selection) {
case 1:
pnum++;
printf("\nEnter first name: ");
scanf("%s", addfname);
printf("Enter last name: ");
scanf("%s", addlname);
printf("Enter phone number (no spaces): ");
scanf("%s", addpnumber);
addentry(pnum, pcontacts, addfname[20], addlname[20], addpnumber[20]);
break;
}
} while (inputtest == 1);
}
}
void addentry(int pnum, entry *pcontacts, char addfname[20], char addlname[20], char pnumber[20]) {
pcontacts = (entry*)malloc(pnum * (sizeof(entry)));
if (pcontacts != NULL) {
strcpy(*pcontacts[pnum - 1].fname, addfname);
printf("\nContact has been added.");
} else {
printf ("No memory is available.\n");
}
}
You get strings from standard input with scanf, but you should tell scanf the maximum number of bytes to store to the destination arrays to avoid buffer overruns:
scanf("%19s", addfname);
...
scanf("%19s", addlname);
...
scanf("%19s", addpnumber);
The way you call addentry is incorrect:
addentry(pnum, pcontacts, addfname[20], addlname[20], addpnumber[20]);
You actually try to read the byte just after the end of addfname, addlname and addpnumber. You should instead pass the arrays themselves, that will be passed to the function addentry as pointers to their first bytes:
addentry(pnum, pcontacts, addfname, addlname, addpnumber);
addentry should reallocate the array with realloc. It should be passed a pointer to the array pointer to it can update the pointer in main.
addentry does not copy the strings correctly: it only copies one, but with a syntax error.
Here is a corrected version:
void addentry(int, entry**, char addfname[20], char addlname[20], char addpnumber[20]);
int main(void) {
int selection = 0;
int inputtest = 1;
int pnum = 0; // keeps track of number of contacts
char addfname[20];
char addlname[20];
char addpnumber[20];
entry *pcontacts = NULL;
for (;;) {
do {
printf("\nPhonebook Menu\n\n");
printf("1:\tAdd contact\n");
printf("2:\tDelete contact\n");
printf("3:\tDisplay contacts\n");
printf("4:\tExit\n");
printf("\nChoose an action (1-4): ");
scanf("%d", &selection);
if (selection < 1 || selection > 4) {
printf("Invalid input. Please enter an integer between 1 and 4.\n");
inputtest = 0;
}
if (selection == 4) {
free(pcontacts); /* OK for NULL */
printf("\nThank you for using this phonebook.");
return 0;
}
switch (selection) {
case 1:
printf("\nEnter first name: ");
scanf("%19s", addfname);
printf("Enter last name: ");
scanf("%19s", addlname);
printf("Enter phone number (no spaces): ");
scanf("%19s", addpnumber);
addentry(pnum, &pcontacts, addfname, addlname, addpnumber);
pnum++;
break;
}
} while (inputtest == 1);
}
}
/* add an entry at position pnum */
void addentry(int pnum, entry **pp, char addfname[20], char addlname[20], char pnumber[20]) {
entry *pcontact = *pp;
pcontacts = realloc(pcontacts, (pnum + 1) * sizeof(entry));
if (pcontacts != NULL) {
*pp = pcontacts; /* update pointer in main */
strcpy(pcontacts[pnum].fname, addfname);
strcpy(pcontacts[pnum].lname, addlname);
strcpy(pcontacts[pnum].pnumber, addpnumber);
printf("\nContact has been added.");
} else {
printf ("No memory is available.\n");
}
}

Resources