issue with the using print function unable to print string - c

when the input is yes in status .the string s does not seem to be able to get printed.
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
int main() {
char name[20],sta[3];
scanf("%s",&name);
scanf("%s",&sta);
if((strcmp("Yes",sta)==0)||(strcmp("yes",sta)==0))
printf("Mrs.%s",name);
if((strcmp("No",sta)==0)||(strcmp("no",sta)==0))
printf("Ms.%s",name);
return 0;
}

I have improved your code based on suggestions in comments.
#include <stdio.h>
#include <string.h>
int main() {
char name[20] = {0},
sta[4] = {0};
scanf("%s", name);
scanf("%s", sta);
if ((strcmp("Yes", sta) == 0) || (strcmp("yes", sta) == 0))
printf("Mrs.%s\n", name);
if ((strcmp("No", sta) == 0) || (strcmp("no", sta) == 0))
printf("Ms.%s\n", name);
return 0;
}
First created sta of size 4 to allow 3 characters of "Yes" to fit in it along with '\0' terminator.
scanf() doesn't require & operator for character strings.
Initialized character array to '\0' (equivalent to ASCII 0).
Removed not required header files and improved formatting a bit.

Related

If statement is not printing out on my system call

I input age as 30 but its not printing my if statement. Can i know why ? Thanks
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#define BUFFSIZE 512
int main()
{
int a;
char *buffer[BUFFSIZE];
write(1,"Please Enter your age: ",23);
a=read(0,*buffer,100);
if(a>21)
write(1,"You are an adult",16);
return 0;
}
This
char *buffer[BUFFSIZE];
declares an array of uninitialized pointers.
This
a=read(0,*buffer,100);
passes the first uninitialized pointer to read, so almost certain returns an error (probably EFAULT).
If you were to fix that (remove the * from both lines), it would still return 3 if you enter 30Enter on the keyboard (3 characters entered)
Fixing all that, you end up with something like:
int main() {
int len;
char buffer[BUFSIZE];
write(1,"Please Enter your age: ",23);
len=read(0,buffer,BUFSIZE-1);
if (len <= 0) {
write(1, "invalid input", 13);
} else {
buffer[len] = '\0';
char *end;
int age = strtol(buffer, &end, 0);
if (*end != '\n')
write(1, "input not a (just) a number", 27);
if(age > 21)
write(1,"You are an adult",16);
}
return 0;
}
There's more stuff you can do with error checking (for example, you might want to ignore spaces on the end of the line, or other questionable input), but this shows where to start.
If you consult the documentation for read you will see that the return value is the number of bytes read. You will need to read the characters in buffer and convert them from a string to an int instead of doing what you are doing.
The C standard library provides functions like atoi and scanf that you can use to convert the string into a number, but it's pretty easy to do it yourself and it's a good exercise for a new C programmer.
Try this out, which changes read for more commonly used fscanf:
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
int main()
{
int a;
write(1,"Please Enter your age: ",23);
fscanf(stdin, "%d",&a);
if(a>21)
write(1,"You are an adult",16);
return 0;
}

If i input too many characters my program either has a 'mremap_chunk(): invalid pointer' or a 'realloc(): invalid old size'

my program was built as a test to input as many sentences as the user want (until he enters -1), and then concatenate all sentences (\n included). If i input some characters is fine, but if i input more then 25 characters i have the two errors listed above, i tried simulating what would happen in paper and i canĀ“t find the problem, help is appreciated, thanks in advance.
The code is displayed below:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(void)
{
char *s = malloc(1), *sentence = malloc(0);
int sSize = 0;
printf("Insert sentences, press '-1' if you want to exit:\n");
do
{
fgets(s,100,stdin);
if(strcmp(s,"-1\n") != 0)
{
sSize += strlen(s);
sentence = realloc(sentence, sSize * sizeof(char));
//s[strcspn(s, "\0")] = '\n';
strcat(sentence, s);
}
}while(strcmp(s,"-1\n") != 0);
printf("==================sentence================\n");
printf("%s", sentence);
return 0;
}
This is a classic buffer overrun problem:
s = malloc(1) - s now points to a one-character buffer.
fgets(s,100,stdin); - reads up to 100 characters into s - which is a one-character buffer.
EDIT
Here's a version which works and doesn't use a separate "sentence buffer":
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(void)
{
const char *terminator = "-1\n";
char *sentences = malloc(100);
char *pNext_sentence;
printf("Insert sentences, press '-1' if you want to exit:\n");
*sentences = '\0';
do
{
sentences = realloc(sentences, strlen(sentences)+100);
pNext_sentence = sentences + strlen(sentences);
fgets(pNext_sentence, 100, stdin);
} while(strcmp(pNext_sentence, terminator) != 0);
*(sentences + (strlen(sentences) < strlen(terminator) ? 0 : strlen(sentences) - strlen(terminator))) = '\0';
printf("==================sentences================\n");
printf("%s", sentences);
free(sentences);
return 0;
}
You must use reallocate memory with realloc before using fgets, which, in your case, reads 100 bytes.
Your string has the initial size of 1.

`read` in C hangs the program when string of length more than 16 entered

I made following program that uses read (system call in C) to get a string from user (of length lesser than 100).
#include<stdio.h>
#include <unistd.h>
#include <string.h>
int main() {
char *s;
int a = read(0, s, 100);
s[a-1] = '\0';
printf("\"%s\" \n read returned: %i; NUL at: %u", s, a, strlen(s));
return 0;
}
What I expected here is, it will get characters until user enters a new-line character. It will then replace that '\n' character by '\0', and print it.
The program works well until I enter 15 or less characters in stdin, but stops working when there are more than 16 characters.
My inputs are as follows:
E:\My Files\Codes>a.exe
1234567890123456
"1234567890123456"
returned = 17; length = 16
E:\My Files\Codes>a.exe
12345678901234567
[My program hanged on this input.]
Why does it only hangs on 16? What is special in this 2^2?
Post script: I used the string.h just to get the length of the string. Once my program starts working good, I will remove it.
I have been testing your code. The faults is: You have a pointer which points nowhere. I solve it reserving and allocating memory for your string (char array). I will post the working code:
#include <stdlib.h> // It is needed for malloc, free, etc...
#include <stdio.h>
#include <unistd.h>
#include <string.h>
int main() {
char *s = malloc(100*sizeof(char)); // Allocate memory with malloc
int a = read(0, s, 100);
s[a-1] = '\0';
printf("\"%s\" \n read returned: %i; NUL at: %u", s, a, strlen(s));
free(s); // You need liberate memory before exit
return 0;
}
Also, other way to solve this, without dynamic memory is:
#include <stdio.h>
#include <unistd.h>
#include <string.h>
int main() {
char s[100]; // s is a char array of 100 elements
int a = read(0, s, 100);
s[a-1] = '\0';
printf("\"%s\" \n read returned: %i; NUL at: %u", s, a, strlen(s));
return 0;
}

strcmp returning only 0 (palindrom algo bug)

Hi I learned in class about the string.h library and specifically about the strcmp function that compares between to strings .
and if the first string appears first in the dictionary it will return a number bigger than 0 , if the second string is bigger than first than it will return a number smaller than 0 , and if they are equil its supposed to return a 0.
ive used it like this :
strcmp(strArr , strrev(strArr));
Feel free to educate me.
The code :
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_LENGTH 100
#define PALINDROM_TRUE 0//because in strcmp if both strings compared are equile the strcmp will return 0.
int main(void)
{
char strArr[MAX_LENGTH];
printf("Enter string (max length 100 chars): ");
fgets(strArr , MAX_LENGTH , stdin);
int pali = strcmp(strArr , strrev(strArr));
if(pali == PALINDROM_TRUE)
{
printf("Palindrom\n");
}
else
{
printf("Not Palindrom\n");
}
system("PAUSE");
return 0;
}
my problem is that the code below when I enter i.e "abc" it prints to the screen Palindrom which it should print Not Palindrom , it never prints Not Palindrom
The reason for this is your call to strrev(). strrev() function works in-place. In other words, strrev works on the same buffer(i.e. strArr array) as the original array, and does not allocate a new space for the reversed string. As a result, once you call strrev() with strArr, the string in strArr is reversed, and all you are doing is comparing the two identical strings: the one in strArr, and again, the one in strArr, both of which are now reversed. (Note that the term both may be misguiding. Actually, there is just a single buffer and both arguments to strcmp point to that one.)
One way to correct this issue is to allocate a second array strArr2 and copy the string into it. Then, reverse the string in strArr2, and call strcmp with strArr and strArr2. Below is how this solution would look like in code.
...
char strArr2[MAX_LENGTH];
...
strcpy(strArr2, strArr);
strrev(strArr2);
int pali = strcmp(strArr , strArr2);
if(pali == PALINDROM_TRUE)
{
printf("Palindrom\n");
}
else
{
printf("Not Palindrom\n");
}
...
Note that you may also have to check the end of strArr for any trailing whitespace characters, due to your specific method of taking input. Any such trailing whitespace character could render your reversing and comparing strategy useless by affecting the result of the comparison.
If you do not have that much space, or if MAX_SPACE is too large a value, another way would be to use a custom comparison function for checking if a string is palindrome without having to use strcmp or strrev.
int pali = strcmp(strArr , strrev(strArr));
This line is obviously the issue.
The call to strrev(strArr) reverses strArr so afterwards when strcmp is called, do you expect strArr to be different? But it's the same variable...
You must create another char array to store the reversed string.
EDIT:
#include <stdio.h>
#include <string.h>
#define MAX_LENGTH 100
int main(void)
{
char str[MAX_LENGTH];
char rev[MAX_LENGTH];
puts("Enter string (max length 100 chars): ");
scanf("%s", str);
strcpy(rev, str);
strrev(rev);
if(strcmp(str, rev) == 0) {
puts("Palindrom");
} else {
puts("Not Palindrom");
}
}
ive added
strArr[strcspn(strArr, "\n")] = 0;
after
fgets(strArr , MAX_LENGTH , stdin);
And it worked , its basicly rewriting the (null) at the end. which was messing up the reverse to include null (0) at the start of the string.
Thanks everyone.
Finsihed Code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_LENGTH 100
#define PALINDROM_TRUE 0//because in strcmp if both strings compared are equile the strcmp will return 0.
int main(void)
{
char strArr[MAX_LENGTH], strArrRev[MAX_LENGTH];
printf("Enter string (max length 100 chars): ");
fgets(strArr , MAX_LENGTH , stdin);
strArr[strcspn(strArr, "\n")] = 0;
strcpy(strArrRev, strArr);
int pali = strcmp(strArr , strrev(strArrRev));
if(pali == PALINDROM_TRUE)
{
printf("Palindrom\n");
}
else
{
printf("Not Palindrom\n");
}
system("PAUSE");
return 0;
}

Removing dots in a string in C

I'm making a little program in C where I would put in a couple of numbers and dots and then delete all the dots (.).
I was thinking about a whileloop but I cannot seem to quite understand what I should do next. So far I got this:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char *argv[]) {
char s[30];
int k=0;
printf("Enter your account number including dots. \n");
gets(s);
printf("Account number without dots:");
while (s[k]!=0)
{
//?????
}
return 0;
Am I on the right track or should I start differently and not use a while loop at all? I can only find solutions where there is a specific string that is not written by the user, but by the programmer...
Put in an IF to only print characters that aren't a dot. Like the others suggested, you should probably change the gets to fgets as well.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char *argv[]) {
char s[30];
int k=0;
printf("Enter your account number including dots. \n");
gets(s);
printf("Account number without dots:");
while (s[k]!=0) {
if ( s[k] != '.' ) {
printf("%c", s[k]);
}
k++;
}
printf("\n");
return 0;
}
With a while loop, I'm also worried that if the user puts in a full 30 characters, you won't reach your exit condition. To avoid this problem, a for loop would be better (since you already know the size of the array). However, if you do it this way, you'll also need to initialize your array "s" to be blank.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char *argv[]) {
char s[30];
int k=0;
printf("Enter your account number including dots. \n");
gets(s);
printf("Account number without dots:");
for ( k = 0 ; k < 30 ; k++ ) {
if ( s[k] != '.' && s[k] != 0 ) {
printf("%c", s[k]);
}
k++;
}
printf("\n");
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char *argv[]) {
char s[30];
int k=0;
printf("Enter your account number including dots. \n");
gets(s);
printf("Account number without dots:");
while (s[k]!=0)
{
if(s[k] == '.')
s[k] = s[k + 1];
k++;
}
s[k] = '\0';
return 0;
#include <stdio.h>
//remove the specified character from str
char *strrmc(char *str, char ch){
char *from, *to;
from = to = str;
while(*from){
if(*from == ch)
++from;
else
*to++ = *from++;
}
*to = '\0';
return str;
}
int main(int argc, char *argv[]){
char s[30] = "192.169.007";
printf("%s\n", strrmc(s, '.'));//192169007
return 0;
}
Here's one way you might go at it - it's different from how you've started, but can easily be modified. It could be improved on as well, but we can quibble about that in further comments. :)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char *argv[]) {
/* Take account number in as argument to executable */
int dotless_length = 30;
char dotless[dotless_length];
int k = 0;
int i = 0;
while (argv[1][k] != '\0' && i < dotless_length) {
if (argv[1][k] >= 48 && argv[1][k] <= 57) { /* ascii decimal codes for 0-9 */
dotless[i] = argv[1][k];
i++;
}
else if (argv[1][k] != '.') {
printf("invalid input: %c\n", argv[1][k]);
return 1;
}
k++;
}
dotless[i] = '\0'; /* null-terminate it! */
printf("Account number without dots: %s\n", dotless);
return 0;
}
Then compile with gcc -Wall -o zdotless filename.c and run with
./zdotless 401.863.3000 as an example.
Notes: This may look more harder since it goes into input sanitation (and cleanliness) a little more than your original - e.g.
not assuming that user input consists solely of numbers and periods,
saving the resulting dotless string (for presumable future manipulations?),
having one place to change the length of dotless (a step towards not hardcoding it), and
not being interactive.
When you call an executable, argv is what you've typed, so argv[0] is the executable name (./zdotless), argv[1] is the next argument (401.863.3000 as a string), and so on if there are more arguments. Since argv[1] is the string representation of your dotty input number, argv[1][0] is the first character of it, etc.
Since we're copying to dotless character-by-character rather than using string manipulation, you've got to tack on a null character manually. (That same null character is what you'd loop until reaching, when initially reading the input string.) Other questions?...

Resources