string not printing properly in C - c

I am encountering a problem while printing out a string using a while loop in a standalone function.
I have the following code:
#include <stdio.h>
int pword(char *);
int main() {
char s[] = "Alice";
pword(s);
return 0;
}
int pword(char *s) {
while(*s!='\0') {
printf("%s", s);
s++;
}
printf("\n");
return 0;
}
This is printing: Aliceliceicecee.

you're printing the offseted word each time, instead of the character.
Try changing (for instance)
printf("%s", s);
by
printf("%c", *s);
or since you don't really need formatting, use
putchar(*s);
(all this means that you're basically rewriting puts with a loop. So if no further processing is required on the characters, maybe you should just stick with standard functions)

%s means expect a const char * argument
%c means expect a character argument. The character argument is printed. Null characters are ignored;
You are looking for later one.
More info on %s: The argument is taken to be a string (character pointer), and characters from the string
are printed until a null character or until the number of characters indicated by the
precision specification is reached; however, if the precision is 0 or missing, all characters up to a null are printed;

Seeing no answer explained what exactly was going on, here is what you are actually doing:
int pword(char *s) { /* s = "Alice" (s is a char* that holds the address of "Alice" string)*/
while(*s!='\0') { /* check if the first char pointed to by s != '\0' */
printf("%s", s); /* print the string that start at s*/
s++; /* move s (the char pointer) 1 step forward*/
} /* s points to "lice" -> "ice" -> "ce" -> "e" */
printf("\n");
return 0;
}
In order to print the string "Alice" you could have just used printf("%s", s); as it would take the address pointed to by s, where "Alice" is stored, and print it until reaching null-terminator ('\0').
If you want to use a loop and print char by char, you should have used printf("%c", *s);. Using %c is meant for printing char where %s is for printing strings. Another thing to note is the s vs *s, where the former is a char* (pointer to char) that can hold number of consecutive chars, and the later (*s)is *(char*) i.e. dereferenced char*, that holds a single char.
To sum up:
print char by char
int pword(char *s) {
while(*s!='\0') {
printf("%c", *s);
s++;
}
printf("\n");
return 0;
}
print the whole string at once
int pword(char *s) {
printf("%s\n", s);
return 0;
}

If you want to print character by character, you should use *s in the printf statement like below.
#include <stdio.h>
int pword(char *);
int main() {
char s[] = "Alice";
pword(s);
return 0;
}
int pword(char *s) {
while(*s!='\0') {
printf("%c", *s);
s++;
}
printf("\n");
return 0;
}

Related

How to return a string by replacing with another string in c

#include<stdio.h>
char str(char *s) {
char s1[100];
printf("another string to replace:");
scanf("%d",s1);
s=s1;
return s;
}
void main() {
char s[100],s2[100];
scanf("%s",s);
s2=str(s);
printf("%s",s);
}
How to return a string by replacing with another string in c??I'm unable to replace the string using functions
There a several things to say about your code.
You can't copy strings using =
The return type is wrong. Must be char*
The scanf format string is wrong. Use %s for strings.
You don't need an extra array in the function. Just scanf directly into s
Never do scanf("%s", ... Always put a limit to it like scanf("%99s", ...
Something like:
char* str(char *s) {
printf("another string to replace:");
scanf("%99s",s);
return s;
}
void main() {
char s[100],s2[100];
scanf("%99s",s);
strcpy(s2, str(s));
printf("%s",s);
}
I am, however, not sure what you want the code to do. As it is now s and s2 just end as identical strings.
If you just want a function that can read a new value into s it can be done like:
void str(char *s) {
printf("another string to replace:");
scanf("%99s",s);
}
void main() {
char s[100];
scanf("%99s",s);
str(s);
printf("%s",s);
}
What you're going to want to do is copy the values of the characters in s1 into your s variable. not just set one equal to the other. either using strcpy or looping through your characters in s1 and copying them directly to the correct locations in s.
https://www.tutorialspoint.com/c_standard_library/c_function_strcpy.htm
this works for me without using strcpy:
#include<stdio.h>
void str(char *s) {
char s1[100];
printf("another string to replace:");
scanf("%s",s1);
// not real safe but we know s and s1 have 100 characters.
for(int i = 0; i < 100; i++) {
s[i] = s1[i];
}
}
int main() {
char s[100],s2[100];
scanf("%s",s);
str(s);
printf("%s",s);
}

Program that copies one string to another which includes the function is printing weird characters

This is the code. It has to have the section before the void main() in it as it is the requirements i was told for the code.The stuff after void strcopy needs to be kept until void main().
#include <stdio.h>
void strcopy(char * string1, char * string2)
{
int i = 0;
while (string1[i] != '\0') {
string2[i] = string1[i];
i++;
}
return;
/* copies string1 to string 2 */
}
void main()
{
char string1[1000], string2[1000];
int i;
printf("Enter the string: \n");
scanf("%[^\n]s", string1);
printf(" %s ", string2);
return;
}
This is what is being printed and I'm stumped. Can someone help me out please?
Enter the string:
hello
t��\�
Thanks
First, you do not call strcopy, so you print just the uninitialized content of string2. Second, in strcopy, you forgot to terminate the target string (note that your loop terminates before the `\0' would be written). Write:
void strcopy(char * string1, char * string2)
{
int i = 0;
while (string1[i] != '\0') {
string2[i] = string1[i];
i++;
}
string2[i]='\0';
return;
/* copies string1 to string 2 */
}
If you do not terminate a string, then any bytes in the target memory are treated as "belonging to the string" until a 0x0 byte is reached. And these bytes might produce such weird output.
But you never called strcopy().
Add the function call after reading input:
strcopy(string1, string2);
Other issues are:
main() function should return int. So, change the definition to: int main(void) {... and return an int value such as return EXIT_SUCCESS;.
You haven't inserted the null byte into your destination. You need it because you are printing it as a string using %s. Add string2[i] = 0; after the while loop.
Remove the s from scanf()'s format specifier. %[^\n] is enough to read upto a newline. Instead you might considering using fgets(). Because scanf() as you use - is susceptible to buffer overflow and generally inferior.

Format "%s" expects and agument of type char* etc, I just want to print the alphabet

Why can't I print the alphabet using this code?
void ft_putchar(char c)
{
write(1, &c, 1);
}
int print_alf(char *str)
{
int i;
i = 0;
while (str[i])
{
if (i >= 'A' && i <= 'Z')
ft_putchar(str[i]);
else
ft_putchar('\n');
i++;
}
return (str);
}
int main ()
{
char a[26];
printf("%s", print_alf(a));
return (0);
}
I get this warning
format ' %s ' expects type 'char*' but argument 2 has type 'int'
How do I print the alphabet using a string, and write function?
Your entire print_alf function looks suspicious.
You are returning str which is of type char *. Therefore the return type of print_alf should to be char * instead of int.
Your while (str[i]) loop makes no sense at all since you are passing uninitialized memory to it. So your code will very likely corrupt the memory since the while loop will continue to run until a '\0' is found within the memory which does not need to be the case within the boundaries of the passed memory (a).
You are not adding a zero termination character ('\0') at the end of the string. This will result in printf("%s", print_alf(a)); printing as many characters beginning at the address of a until a '\0' is found within the memory.
Here is a suggestion how to fix all that problems:
char *print_alf(char *str, size_t len)
{
char letter;
if ((str) && (len >= 27)) // is str a valid pointer and length is big enough?
{
for (letter = 'A'; letter <= 'Z'; letter++) // iterate all characters of the alphabet
{
*str = letter;
str++;
}
*str = '\0'; // add zero termination!!!
}
else
{
str = NULL; // indicate an error!
}
return (str);
}
int main()
{
char a[26 + 1]; // ensure '\0' fits into buffer!
printf("%s", print_alf(a, sizeof(a)));
return (0);
}
Make up your mind whether print_alf should return a string which you then print with printf or whether print_alf should be a void function that does the printing, which you should then just call without printf. At the moment, your code tries to be a mixture of both.
The easiest way is to just print the alphabet:
void print_alf(void)
{
int c;
for (c = 'A'; c <= 'Z'; c++) putchar(c);
}
Call this function like so:
print_alf(); // print whole alphabet to terminal
A more complicated variant is to fill a string with the alphabet and then print that string. That's what you tried to achieve, I think. In that case, you must pass a sufficiently big buffer to the function and return it. Note that if you want to use the string functions and features of the standard lib (of which printf("%s", ...) is one) you must null-terminate your string.
char *fill_alf(chat *str)
{
int i;
for (i = 0; i < 26; i++) str[] = 'A' + i;
str[26] = '\0';
return str;
}
It is okay to return the buffer that was passed into the function, but beware of cases where you return local character buffers, which will lead to undefined behaviour.
You can call it as you intended in your original code, but note that you must make your buffer at least 27 characters big to hold the 26 letters and the null terminator:
char a[27];
printf("%s\n", fill_alf(a));
Alternatively, you could do the filling and printing in twp separate steps:
char a[27];
fill_alf(a); // ignore return value, because it's 'a'
printf("%s\n", a); // print filled buffer
If you just want to print the alphabet, the print_alf variant is much simpler and straightforward. If you want to operate further on the alphabet, eg do a shuffle, consider using fill_alf.
Your print_alf(char *str) function actually returns an integer which causes the error (it is defined to return int). When you specify %s to printf it expects characters, not numbers.
You can fix this by changing the return type of your function to char and if everything else works in your code you'll be good to go.

Using Pointers and strtok()

I'm building a linked list and need your assistance please as I'm new to C.
I need to input a string that looks like this: (word)_#_(year)_#_(DEFINITION(UPPER CASE))
Ex: Enter a string
Input: invest_#_1945_#_TRADE
Basically I'm looking to build a function that scans the DEFINITION and give's me back the word it relates to.
Enter a word to search in the dictionary
Input: TRADE
Output: Found "TREADE" in the word "invest"
So far I managed to come up using the strtok() function but right now I'm not sure what to do about printing the first word then.
Here's what I could come up with:
char split(char words[99],char *p)
{
p=strtok(words, "_#_");
while (p!=NULL)
{
printf("%s\n",p);
p = strtok(NULL, "_#_");
}
return 0;
}
int main()
{
char hello[99];
char *s = NULL;
printf("Enter a string you want to split\n");
scanf("%s", hello);
split(hello,s);
return 0;
}
Any ideas on what should I do?
I reckon that your problem is how to extract the three bits of information from your formatted string.
The function strtok does not work as you think it does: The second argument is not a literal delimiting string, but a string that serves as a set of characters that are delimiters.
In your case, sscanf seems to be the better choice:
#include <stdlib.h>
#include <stdio.h>
int main()
{
const char *line = "invest_#_1945 _#_TRADE ";
char word[40];
int year;
char def[40];
int n;
n = sscanf(line, "%40[^_]_#_%d_#_%40s", word, &year, def);
if (n == 3) {
printf("word: %s\n", word);
printf("year: %d\n", year);
printf("def'n: %s\n", def);
} else {
printf("Unrecognized line.\n");
}
return 0;
}
The function sscanf examines a given string according to a given pattern. Roughly, that pattern consists of format specifiers that begin with a percent sign, of spaces which denote any amount of white-space characters (including none) and of other characters that have to be matched varbatim. The format specifiers yield a result, which has to be stored. Therefore, for each specifier, a result variable must be given after the format string.
In this case, there are several chunks:
%40[^_] reads up to 40 characters that are not the underscore into a char array. This is a special case of reading a string. Strings in sscanf are really words and may not contain white space. The underscore, however, would be part of a string, so in order not to eat up the underscore of the first delimiter, you have to use the notation [^(chars)], which means: Any sequence of chars that do not contain the given chars. (The caret does the negation here, [(chars)] would mean any sequence of the given chars.)
_#_ matches the first delimiter literally, i.e. only if the next chars are underscore hash mark, underscore.
%d reads a decimal number into an integer. Note that the adress of the integer has to be given here with &.
_#_ matches the second delimiter.
%40s reads a string of up to 40 non-whitespace characters into a char array.
The function returns the number of matched results, which should be three if the line is valid. The function sscanf can be cumbersome, but is probably your best bet here for quick and dirty input.
#include <stdio.h>
#include <string.h>
char *strtokByWord_r(char *str, const char *word, char **store){
char *p, *ret;
if(str != NULL){
*store = str;
}
if(*store == NULL) return NULL;
p = strstr(ret=*store, word);
if(p){
*p='\0';
*store = p + strlen(word);
} else {
*store = NULL;
}
return ret;
}
char *strtokByWord(char *str, const char *word){
static char *store = NULL;
return strtokByWord_r(str, word, &store);
}
int main(){
char input[]="invest_#_1945_#_TRADE";
char *array[3];
char *p;
int i, size = sizeof(array)/sizeof(char*);
for(i=0, p=input;i<size;++i){
if(NULL!=(p=strtokByWord(p, "_#_"))){
array[i]=p;//strdup(p);
p=NULL;
} else {
array[i]=NULL;
break;
}
}
for(i = 0;i<size;++i)
printf("array[%d]=\"%s\"\n", i, array[i]);
/* result
array[0]="invest"
array[1]="1945"
array[2]="TRADE"
*/
return 0;
}

Is there any function available for printing some characters instead of whole strings?

see
char str[] = "hello world";
printf("%s",str);
printf statement prints the all character in string before reaching '\0'
so what if i want to print just 4 1st character of str on stdout?
You can just specify the field width in the printf format string:
#include <stdio.h>
int main(void)
{
const char *s = "Hello world !";
printf("%.4s\n", s);
return 0;
}
or, if you want to specify the field width at run-time:
#include <stdio.h>
int main(void)
{
const char *s = "Hello world !";
const int fw = 4;
printf("%.*s\n", fw, s);
return 0;
}
In either case the output will be:
Hell
You can use %c in your format string:
printf("%c", *s);
prints 'H'
To print an arbitrary char:
printf("%c", s[3]);
prints 'l'
For the first character, you can just use:
printf ("%c", *str); // or
printf ("%c", *(str+0)); // or
printf ("%c", str[0]);
For a different character, just reach out and grab it by using an offset. For the second l at offset 3:
printf ("%c", str[3]); // or
printf ("%c", *(str+3));
For a substring, you can use a combination of that method along with the maximum field width feature of printf:
printf ("%.2s", str+3); // prints "lo"
With all these solutions, you want to make sure you don't start on the wrong side of the null terminator. That wouldn't be a good thing :-)
If you want a generalised solution that will work for any string, and is relatively safe in terms of finding the starting point, you can use:
void outSubstr (FILE *fh, char *str, size_t start, size_t sz, int padOut) {
if (start >= strlen (str)) {
if (padOut)
fprintf (fh, "%*s", sz, "");
return;
}
if (padOut)
fprintf (fh, "%-*.*s", sz, sz, str + start);
else
fprintf (fh, "%-.*s", sz, str + start);
}
The parameters are as follows:
fh is the file handle to write to.
str is the start of the string.
start is the offset to start printing from.
sz is the maximum number of characters to print.
padOut is a flag indicating that sz is also the minimum size. Output will be padded with spaces on the right if there are not enough characters in the string to satisfy the size.
This will print up to 4 characters.
printf("%.4s", str);
there is also a "substr()" function
that return the substring from complete string.
example
printf("%s",substr(str,0,4));
it has syntax like this
substr(arrayName,charStartingPosition, lengthOfCharacters);
i hope this is easy to understand and no need to write more than 1 statement.
Really less painful for the system :
int main(void)
{
char c;
c = 'z';
write(1, &c, 1);
}
No need for heavy stdio here
Then you can ...
char *s = "Hello, World!";
write(1, s, numberOfChars);
Or if you really want to do it char by char:
void printnchars(char *s, int n)
{
int i;
i = 0;
while (i <= n)
{
write(1, s + i, 1);
i++;
}
}
numOfChars = 4;
printf("%.*s\n", numOfChars, "Hello, world!");
Where numOfChars is the quantity of characters that you want to print.

Resources