How do I properly 'printf' an integer and a string in C? - c

I have the following code:
char *s1, *s2;
char str[10];
printf("Type a string: ");
scanf("%s", str);
s1 = &str[0];
s2 = &str[2];
printf("%s\n", s1);
printf("%s\n", s2);
When I run the code, and enter the input "A 1" as follow:
Type a string: A 1
I got the following result:
A
�<�
I'm trying to read the first character as a string and the third character as an integer, and then print those out on the screen. The first character always works, but the screen would just display random stuffs after that.... How should I fix it?

You're on the right track. Here's a corrected version:
char str[10];
int n;
printf("type a string: ");
scanf("%s %d", str, &n);
printf("%s\n", str);
printf("%d\n", n);
Let's talk through the changes:
allocate an int (n) to store your number in
tell scanf to read in first a string and then a number (%d means number, as you already knew from your printf
That's pretty much all there is to it. Your code is a little bit dangerous, still, because any user input that's longer than 9 characters will overflow str and start trampling your stack.

scanf("%s",str) scans only until it finds a whitespace character. With the input "A 1", it will scan only the first character, hence s2 points at the garbage that happened to be in str, since that array wasn't initialised.

Try this code my friend...
#include<stdio.h>
int main(){
char *s1, *s2;
char str[10];
printf("type a string: ");
scanf("%s", str);
s1 = &str[0];
s2 = &str[2];
printf("%c\n", *s1); //use %c instead of %s and *s1 which is the content of position 1
printf("%c\n", *s2); //use %c instead of %s and *s3 which is the content of position 1
return 0;
}

Related

How to print the nth term of a string using scanf function?

The console will not do anything after the user has entered a string.
I have got the code to work using char string="enteraword" and taking out the whole printf and scanf function, however I need the code to work with a scanf function.
#include <stdio.h>
#include <string.h>
int main()
{
char* string;
printf("Enter a word: ");
scanf("%s", string);
char c=string[1];
printf("The second letter in %s is %c", string, c);
return 0;
}
This code has undefined behavior, you're passing an uninitialized pointer to scanf(), asking it to store a string there.
Also, remember that %s will stop at whitespace, so it's very unclear what "terms" should mean here.
Try e.g.:
char string[1024];
if(scanf("%1023s", string) == 1 && string[0] != '\0')
{
const char c = string[1];
printf("The second letter of '%s' is '%c'\n", string, c);
}

Abort trap: 6 error with strncat()

I am trying to write code where I must implement versions of the library functions strncpy, strncat, and strncmp but it gives me Abort trap: 6 error while running. Any ideas are much appreciated:
#include<stdio.h>
#include<string.h>
int main() {
char str1[400];
printf ("Enter the first string: ");
fgets (str1, 400, stdin);
char str2[400];
printf ("Enter the second string: ");
fgets (str2, 400, stdin);
int num;
printf ("Enter the number: ");
scanf ("%d", &num);
char dest[num];
strncpy(dest, str2, num);
dest[num] = '\0';
printf ("strncpy is %s \n", dest);
int lengthStr1 = strlen (str1);
char str1copy [lengthStr1];
strncpy(str1copy, str1, lengthStr1);
str1copy [lengthStr1] = '\0';
printf ("str1copy is %s \n", str1copy);
strncat(str1copy, dest, num);
printf ("strncat is %s\n", str1copy);
}
I know that my strncpy section works.
An array of size n has indexes 0 to n-1.
When you declare your array like this:
char dest[num];
Then do this:
dest[num] = '\0';
You are accessing an offset one byte past the end of the array. Doing so invokes undefined behavior, which in this case manifests in a crash.
Since you want to copy num bytes into this array, the size should be 1 more to make room for the null byte.
char dest[num+1];
Then setting dest[num] makes sense.
There's a similar error with str1copy. In this case however using lengthStr1-1 as the offset isn't enough. You copy in lengthStr bytes from str1 then an additional num bytes from dest. So the length has to be the sum of those, plus 1 for the null terminating byte.
char str1copy [lengthStr1+dest+1];
strncpy(str1copy, str1, lengthStr1);
str1copy [lengthStr1] = '\0';
printf ("str1copy is %s \n", str1copy);
strncat(str1copy, dest, num);
str1copy [lengthStr1+dest] = '\0';
printf ("strncat is %s\n", str1copy);

Read a string as an input using scanf

I am new to C language and I am trying read a character and a string (a sentence; max-length 25) from a user.
Not sure what I am doing wrong in the following lines of code, its giving me an error "Segment Fault".
#include <stdio.h>
int main(){
char * str[25];
char car;
printf("Enter a character: ");
car = getchar();
printf("Enter a sentence: ");
scanf("%[^\n]s", &str);
printf("\nThe sentence is %s, and the character is %s\n", str, car);
return 0;
}
Thanks!
You have to make four changes:
Change
char * str[25];
to
char str[25];
as you want an array of 25 chars, not an array of 25 pointers to char.
Change
char car;
to
int car;
as getchar() returns an int, not a char.
Change
scanf("%[^\n]s", &str);
to
scanf( "%24[^\n]", str);
which tells scanf to
Ignore all whitespace characters, if any.
Scan a maximum of 24 characters (+1 for the Nul-terminator '\0') or until a \n and store it in str.
Change
printf("\nThe sentence is %s, and the character is %s\n", str, car);
to
printf("\nThe sentence is %s, and the character is %c\n", str, car);
as the correct format specifier for a char is %c, not %s.
str is an array of 25 pointers to char, not an array of char. So change its declaration to
char str[25];
And you cannot use scanf to read sentences--it stops reading at the first whitespace, so use fgets to read the sentence instead.
And in your last printf, you need the %c specifier to print characters, not %s.
You also need to flush the standard input, because there is a '\n' remaining in stdin, so you need to throw those characters out.
The revised program is now
#include <stdio.h>
void flush();
int main()
{
char str[25], car;
printf("Enter a character\n");
car = getchar();
flush();
printf("Enter a sentence\n");
fgets(str, 25, stdin);
printf("\nThe sentence is %s, and the character is %c\n", str, car);
return 0;
}
void flush()
{
int c;
while ((c = getchar()) != '\n' && c != EOF)
;
}
// This is minimal change to your code to work
#include <stdio.h>
int main(){
char car,str[25];
printf("Enter a character: ");
car = getchar();
printf("Enter a sentence: ");
scanf("%s", str);
printf("\nThe sentence is %s, and the character is %c\n", str, car);
return 0;
}

strlen doesn't work even with #include <string.h> in C

Does it not return an int or something?
This is a snippet of my code:
int wordlength(char *x);
int main()
{
char word;
printf("Enter a word: \n");
scanf("%c \n", &word);
printf("Word Length: %d", wordlength(word));
return 0;
}
int wordlength(char *x)
{
int length = strlen(x);
return length;
}
Function strlen is applied to strings (character arrays) that have the terminating zero. You are applying the function to a pointer to a single character. So the program has undefined behaviour.
Change this part:
char word;
printf("Enter a word: \n");
scanf("%c \n", &word);
to:
char word[256]; // you need a string here, not just a single character
printf("Enter a word: \n");
scanf("%255s", word); // to read a string with scanf you need %s, not %c.
// Note also that you don't need an & for a string,
// and note that %255s prevents buffer overflow if
// the input string is too long.
You should also know that the compiler would have helped you with most of these problems if you had enabled warnings (e.g. gcc -Wall ...)
Update: For a sentence (i.e. a string including white space) you would need to use fgets:
char sentence[256];
printf("Enter a sentence: \n");
fgets(sentence, sizeof(sentence), stdin);

Character Pointers with Palindrome Checker in C

This is code I wrote that checks if a string is a palindrome or not. I need to revise this code so that it uses character pointers in it. Could someone give me some suggestions/tips...or show me how to do that? Thanks
#include <stdio.h>
#include <string.h>
#include <ctype.h>
int main(){
char string1[20];
int i, length;
int flag = 0;
printf("Enter a string: ");
scanf("%s", string1);
length = strlen(string1);
for(i=0;i < length ;i++){
if(toupper(string1[i]) != toupper(string1[length-i-1])){
flag = 1;
break;
}
}
if (flag)
printf("%s is not a palindrome \n\n", string1);
else
printf("%s is a palindrome \n", string1);
return 0;
}
In your code you use string1[i] to access the current element from the beginning of the string, and string1[length-i-1] to access the current element from the end of the string. You could create two pointers, pb and pe, and then move them toward each other.
To define pointers, use this:
char *pb = &string1[0]; // Or just string1, compiler will convert it to pointer
char *pe = &string1[length-1];
To advance the pointers toward each other, use pb++ and pe--.
To see if the pointers have not crossed each other , check that pb < pe. Currently, your program checks the string twice; there's no need to do that - you can stop as soon as pe becomes less than or equal to the pb.
To access the character pointed to by the current pointer, use
toupper(*pb) != toupper(*pe)
You can combine the check with advancing the pointers, like this:
toupper(*pb++) != toupper(*pe--)
Note: it is not safe to use %s, because when users enter more characters than fits in your string1 buffer overrun results. You should specify the length of the buffer, like this:
scanf("%19s", string1); // Leave one char for null terminator
I'm not sure I completely understand the question, but I think this answers it. You actually are using character pointers. char string1[20] is the same as char *string1. The difference is that you've basically assigned the pointer to a block of memory. You could access the string in this way.
char string[20] = "foo";
printf("%c\n", string[0]); // will print 'f'
printf("%c\n", *string); // will also print 'f'
printf("%c\n", string[1]); // will print the first 'o'
printf("%c\n", *(string + 1)); // will also print the first 'o'
with char * it goes like this
#include <stdio.h>
#include <string.h>
#include <ctype.h>
int main()
{
char string1[20];
int i, length;
int flag = 0;
printf("Enter a string: ");
scanf("%s", string1);
length = strlen(string1);
char *start=string1;
char *end=&string1[length-1];
//only check upto half
for(i=0;i <= (length-1)/2 ;i++)
{
if(toupper(*(start+i)) != toupper(*(end-i)))
{
flag = 1;
break;
}
}
if (flag)
printf("%s is not a palindrome \n\n", string1);
else
printf("%s is a palindrome \n", string1);
return 0;
}
cant we just copy the original string to another array, and then use strrev() to reverse the copied string and then finally compare the original string with the reversed string?
Like this
1.get new string
2.copy string to new array
3.reverse the copied string using strrev
4.use strcmp to check if both are same or not?
this seemed easier
(i am a beginner so please correct me if i am wrong)

Resources