C - Segmentation fault when using strlen? - c

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.

Related

why for loop in program is not working correctly.it show display correct output but giving strange output

#include<stdio.h>
#include<string.h>
int main()
{
char username[5][10]={"akshay","shubham","gaurav","rahul","amit"};
int i,a=1;
char urname[10];
char pass[10];
printf("enter the Username : ");
scanf("%s",urname);
printf("enter the passwword : ");
scanf("%s",pass);
for(i=0;i<5;i++)
{
if(strcmp(&username[i][0],urname)==0) //username check
{
if(strcmp("helloworld",pass)==0) //password check
{
printf("correct username");
break;
}
else
printf("wrong pass");
break;
}
else
printf(" wrong username");
}
return 0;
}
//i wanted to make a login page but by some mean it is not working correctly please help me out...
Couple of things wrong with your code. First, the array size of 10 is insufficient for a string like "helloworld", in which we see 10 characters appear. You didn't count the '\0' byte at the end of the string. See this for details: What does the symbol \0 mean in a string-literal?
You also display an error immediately after you find a username mismatch. You should only do so in the end, after you have checked every entry in the username[][] array and perhaps set a flag.
#include <stdio.h>
#include <string.h>
int main(void)
{
char username[5][10] = {"akshay", "shubham", "gaurav", "rahul", "amit"};
int i, uname_flag = 0;
char urname[11];
char pass[11];
printf("enter the Username : ");
if (scanf("%10s", urname) != 1) // limit characters to be read to 10, to avoid buffer overflow
// also check the return value of scanf for input failure
{
return 1;
}
printf("enter the passwword : ");
if (scanf("%10s", pass) != 1)
{
return 1;
}
for (i = 0; i < 5; i++)
{
if (strcmp(username[i], urname) == 0) //username check
{
uname_flag = 1; // username is correct
if (strcmp("helloworld", pass) == 0) //password check
{
printf("correct username & pass");
break;
}
else
{
printf("wrong pass");
break;
}
}
}
if (uname_flag == 0) // check outside the loop
{
printf("wrong username\n");
}
return 0;
}

How do i get a program to loop until a character is entered?

What I'm exactly trying to achieve is: You enter your name, get a response like 'your name is', and if you enter a number you get a response like 'invalid input' which loops you back to the 'Enter your name' part
#include <stdio.h>
char i[20];
int result;
int main()
{
void findi(); // im trying to loop it back here if a number is entered instead of a character
printf("Enter your name\n");
result = scanf("%s", &i);
while(getchar() != '\n'){ //dont know how to make it work without the '!'
if(result = '%s'){
printf("Your name is: %s", &i);
return 0;
}
else{
printf("Invalid input"); //doesnt work
findi();
}
}
}
//program just ends after a character is entered instead of continuing
Using &i (char(*)[20]) for %s (expects char*) invokes undefined behavior.
The condition result = '%s' (assign implementation-defined value to result without checking its value) looks weird.
Calling findi() (not disclosed here) from main() need not mean a loop.
Try this:
#include <stdio.h>
#include <ctype.h>
int main(void)
{
char i[20];
printf("Enter your name\n");
/* an infinite loop (loop until return or break) */
for (;;) {
int number_exists = 0, j;
/* limit length to read and check the result*/
if (scanf("%19s", i) != 1) {
printf("read error\n");
return 1;
}
/* check if a number is entered */
for(j = 0; i[j] != '\0'; j++) {
if (isdigit((unsigned char)i[j])) {
number_exists = 1;
break;
}
}
/* see the result */
if (number_exists) {
/* one or more number is entered */
printf("Invalid input\n");
} else {
/* no number is entered : exit from the loop */
printf("Your name is: %s\n", i);
break;
}
}
return 0;
}

C string input overflows other string input

I'm doing a simple console type command system, and inputting a command will scanf an integer and then will scanf a string, but the contents of the second string overflows the original string
while (exit == 0) {
scanf("%s", input);
if (strcmp(input, "parent") == 0) {
free(input);
ptemp = malloc(sizeof(node_p));
printf("Id: ");
scanf("%d", &ptemp->itemid);
printf("\nElement:");
scanf("%s", ptemp->element);
add_parent_node(parent, ptemp->itemid, ptemp->element);
free(ptemp);
}
}
ptemp is a pointer to a struct containing:
int itemid;
char *element;
I've tried using arrays with predefined size, but nothing seems to work...
Someone that made a comment about nothing overflowing is correct. What you were missing were (in laymans terms) a reservation for characters. Declaring something as char* instead of char[xx] means that you're prepared to reference another part of memory that you're allowed to manipulate with your characters. To keep things simple, I rewritten your code so your program works. Keep in mind that this code relies on users entering strings that are less than 100 to 200 characters long. Feel free to increase the number in square brackets if you need more characters.
I also made an add_parent_node function to verify that the data processing works.
If you want to get a little paranoid and you feel your systems implementation of scanf is screwy, then you can place the following under the while statement:
memset(ptemp,0,sizeof(ptemp));
What that does is floods the entire struct with null characters. This means the value of itemid would be zero since zero is null, and element would be 200 null characters.
Here's the code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct{
int itemid;
char element[200]; //fixed array of chars to actually store a string
}mycollection;
void add_parent_node(char* parentnodename,int itemid,char* element){
printf("Added node as follows\n");
printf("Parent: %s\n",parentnodename);
printf("Item ID: %d\n",itemid);
printf("Element: %s\n\n",element);
}
int main(){
char input[100]; //limit command to 99 characters
mycollection ptemp[1];
while(1){ //while(1) = endless loop
printf("\nEnter command: ");
scanf("%s", input);
if (strcmp(input, "parent") == 0) {
printf("\nId: ");
scanf("%d", &ptemp->itemid);
printf("\nElement:");
scanf("%s", ptemp->element);
add_parent_node("im_the_parent", ptemp->itemid, ptemp->element);
}
if (strcmp(input, "exit") == 0) {
return 0; //return 0 = exit
}
}
}
If you don't want to change anything outside your while loop I think this is what you can do.
while (exit == 0) {
scanf("%s", input);
if (strcmp(input, "parent") == 0) {
if(0 == ptemp ){
/* Allocate memory only once and reuse it.*/
ptemp = malloc(sizeof(node_p));
/* Allocate memory for element. */
ptemp->element = malloc(sizeof(char) * 1024 /* Max string len + 1 */)
}
printf("Id: ");
scanf("%d", &ptemp->itemid);
printf("\nElement:");
scanf("%s", ptemp->element);
add_parent_node(parent, ptemp->itemid, ptemp->element);
}
else if (strcmp(input, "exit") == 0) {
if(0 != ptemp){
/* If memory is allocated for ptemp, free it. */
if(0 != ptemp->element){
free(ptemp->element);
ptemp->element = 0;
}
free(ptemp);
ptemp = 0;
}
free(input);
input = 0;
exit = 1;
break;
}
}

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");
}
}

Shuffle a string input by user

#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!

Resources