I'd like your help with understand what can be an input from a user to the following program that can make the output:U%ae'$ffq' ong string
int main(void) {
int i=0;
char j[22]="This is a long string", k[3];
scanf("%2s ", k);
sprintf(j, k);
printf("%s", j);
for (; i< 21; printf("%c", j[i++]))
;
return 1;
}
I don't understand couple of things:
k can get only two chars from the user- Is this what "%2s" means, no? and then writes into the array pointed by j the content pointed by the array k, so j is not pointed to k, but if we'll j[5] we'll still get i. so I don't understand how can we get this input whatsoever since the input would be chopped to two chars j[0], j[1] would be the two chars from the input and the rest of j[i] would be the original rest of "This is a long string".
I'm only guessing here, but the problem is probably with the loop. You do not check for the string terminator, but print all of the array regardless of if the string has ended or not.
If you change the loop to this:
for (; i < 22 && j[i] != '\0'; printf("%c", j[i++])) ;
You should get the expected output.
(Note: I also changed 21 to 22 which is the size of the array. You can of course do i <= 21 as that is the same.)
Edit: Rereading the question after the comment from hmjd.
If the input as read by scanf contains a percentage ('%') character the call to sprintf afterwards will try to parse it as a formatting code. If I test this program with the input %d123, then k will be "%d" as expected, but the resulting array j will be "192795408\0long string".
Related
I don't understand Why don’t we have to print strings in for loop ? In normal cases we need to print arrays in for loop. For example, if we want to print the array of integers. It will be like this:
int a[n];
for (i = 0; i < n; i++){
printf("%d", a[i]);
}
But for strings like:
char s[100] = " Hello ";
printf("%s\n", s);
it is enough to write the name of array.
EDIT: It seems like I didnt ask my question properly as some of you wrote answers which is not related to my question.I edit my question.
Strings terminate with the empty character '\0', that's how it is possible to know when a string ends even without explicitly passing its length.
The difference is that C-style strings (which are char arrays) are zero-terminated, whereas int arrays are normally not zero terminated.
Theoretically, you could also create an int array which is zero-terminated and print that in a loop:
int a[] = {5,7,3,0};
for (i=0;a[i]!=0;i++)
{
printf("%d",a[i])
}
However, the problem with zero-terminated int arrays is that the number 0 could be a meaningful value, so you cannot be sure that it really is the end of the array when you encounter that value. With strings, however, the ASCII-Code 0 does not represent a meaningful value, so you can be reasonably sure that you have reached the end of the string.
Your example is far from analogous. %d refers to a single integer, while %s refers to an entire (but still single) string.
You are not passing the size of the array n[] to printf either - rather you are calling printf n times. You are printing one int just as you are printing one string.
The actual string length is not known a priori, rather printf iterates the string until it encounters the \0 terminator. Equivalent to:
for( int i = 0; s[i] != '\0'; i++)
{
printf( "%c", s[i] ) ;
}
because
char s[100] = " Hello ";
is equivalent to:
char s[100] = { ' ', 'H', 'e', 'l', 'l', 'o', ' ', '\0' } ;
Strings are multiple characters all at once. You cannot ask for a specific character from a string. If you want to do so, you must refer to it as an array of chars like this
for (i = 0; i < n; i++){
printf("%c", s[i]);
}
It is because you are already providing the parameter which is "%s" to the printf function which already has a definition telling it how to print a string.
Hope it helps.
One of the reason is that char only takes 1 byte of memeory and when you just press a character, the first index of array is filled up completely and it moves on to the next one till it encounters NULL character. This is not the case with integer array where the size is more than 1 byte and is machine dependent. So you cannot escape the first index by just pressing the number less than the maximum range. If you try to do this, it will store your numbers in first index only and hence a for loop is required there.
I am trying to do a FLAMES program as an assignment and since I can't exactly post my whole code here, I will type in the part of the code that seems to be causing me errors since whenever I print out something, there are unexpected extra characters going with the output.
I used a similar code as this one:
int main(){
char chari[100], temp[100];
int i, c;
printf("Enter a name: \n");
scanf(" %[^\n]s", chari);
for (i=1; chari[i]!='\0'; i++)
{
printf("%i\n", i);
}
c = i;
for (i=0; i<c; i++)
{
printf("%i < %i\n", i, c);
temp[i] = chari[i];
}
printf("%s \n", temp);
return 0;
}
I've been tweaking the codes for hours now but I still can't seem to find the problem. I'm also counting the number of letters in the string so I can stop some part of my program later on.
Input: cool
Expected output: cool
Actual Output: cool(<-t
You forgot to copy the terminating null character.
After your first loop c = i; holds the index of the 0 byte.
In the second loop you run until i < c, i.e. you do not copy that 0 byte
Without terminating nul your string is as long as another random 0 byte is found in memory.
Within a function only static variables are initialized. Hence your temp array hold indetermined values and you cannot rely to get a 0 character where you need it.
You need to copy 1 more byte.
I am fairly new to C programming and trying to improve. I have seen a few question similar to this and tried to implement their suggestions using strncpy but it still won't work. Can anyone give me a pointer in the right direction? Thanks.
The aim of the code is to be given a string and split it on finding a blank space. I am deliberately not using strtok().
#include <stdio.h>
#include <string.h>
#include <ctype.h>
char str[10] ;
char word[10] ;
int i, j, k, l ;
int main()
{
printf("Please enter a string of ten characters and I'll find the blanks\n") ;
fgets(str,10,stdin) ;
printf("Original string is %s\n", str) ;
j = 0 ;
for(i == 0 ; i < 10 ; i++){
if(!isblank(str[i])){
strncpy(word[j], &str[i], 1) ;
printf("i = %d, j = %d, str[i] = %c, word[j] = %c\n",i, j, str[i], word[j]) ;
j++ ;
}else{
printf("%s\n",word) ;
j = 0 ;
}
}
return 0 ;
}
The problem, as I see it, is in
for(i == 0 ; i < 10 ; i++)
^^
You should be using the assignment (=), like
for(i = 0 ; i < 10 ; i++)
to set the initial value of i. Otherwise, by accessing the value of an uninitialized local variable (whose value is indeterminate without an initialization), your code will invoke undefined behavior.
Then, the usage of strncpy() also looks wrong, you're not passing a char *, as required for the first argument.
Now, that said, two more things,
To copy a single char one at a time, you can simply use the assignment , like
word[j] = str[i];
You should only loop over the input array till the valid entries, not the whole size (10). In case, the input is smaller, you'll again hit UB.
I think your problem is no pointer to the dest argument in the strncpy function.
strncpy(word[j], &str[i], 1) ;
^
Add a pointer to the destination for the strncpy function
strncpy(&word[j], &str[i], 1) ;
as well as fixing the issue mentioned by Sourav Ghosh and you should have it.
As i commented on the #James, this is a REAL issue on non-BSD where there is no strsep().
strtok() and strtok_r() are both IMO fundamentally flawed in that they unilaterally skip any sequence of >1 adjacent delimiters.
I used this solution:
https://www.geeksforgeeks.org/c-program-replace-word-text-another-given-word/
in order to fill the above with space gaps so that I can get a proper tokenization of ALL my payload.
Reader beware, the solution above has a flaw...so you might need to call it more than once...Not optimal, but if you are in a hurry as I was, I used it and it works.
while(strstr(token, ";;")!=NULL) {
token = replaceWord(token, ";;", "; ;");
(void) sprintf (v_sg_TempMsg, "Massaged the input agsId to token:[%s]", token);
printf(v_sg_TempMsg);
++tokenCounter;
if(tokenCounter==15) {
break;
}
}//while(strstr(token, ";;")!=NULL) {
...and the above is a hack to get call the code that is flawed to eventually remove all the occurrences of the delimiters...this is dirty dirty code, so please, no flamers...it is here to HELP people who are blocked because of a lack of an alternative to strtok() and strtok_r() skipping.
This question already has answers here:
What would be the simplest way to alpha sort an array of chars in C?
(7 answers)
Closed 7 years ago.
Hi I'm pretty new to using C.
My teacher told me to code a function to sort characters in a string alphabetically by using array & the fact that when a scanf() a string, the first character is called and the rest are saved in the buffer.
(I haven't learnt about pointers yet.)
For example, if I type in badf and space(signalling "an end", or the sentinel value for end of string), the function should return abdf.
I'm stuck here. It's my first ever stackoverflow question! Please help. Thanks.
#include <stdio.h>
#include <string.h>
int main() {
char arr[100];
char front_char, first_char;
// set the variables
int i, j, k, l;
printf("Enter a string and press space to end\n");
// get the input using scanf, which will just get the first character and save the rest in buffer
scanf("%c", &first_char);
// assign the first_character in arr[0] for initialization
arr[0] = first_char;
// 32 is "space" in ascii code. Space is used as a sentinel value. User is supposed to press space at the end of the String
while(front_char != 32) {
// get the "second" character from buffer and ass. repeat this until the next character in buffer is 32, or "space"
scanf("%c" , &front_char);
// load character from buffer, and check if its assigned number in ascii code is smaller than characters in array
for(i = 1; front_char != 32; i++) {
for(j = 0; j < i; j++) {
// go through the previously aligned array to compare the ascii number of the loaded character from buffer
if(arr[j] <= front_char) {
continue;
} else {
// run through the previously aligned array, and if a character with bigger ascii number comes up,
for(k = i-1; k >= j; k--) {
// assign/push the values in array to the next index(i don't know how to describe this, but I hope you see what I mean..)
arr[k+1] = arr[k];
}
}
// assign the loaded character according its ascii number size
arr[j] = front_char;
}
}
// print the result
for(l = 0 ; l < i ; l++){
printf("%c", arr[l]);
}
}
return 0;
}
To get to your final solution, you have to get through three intermediate steps:
Read in the string successfully
Address individual characters in the string
Transpose characters in the string
You definitely have bugs (ameyCU's answer).
Try first to read in the string, and just print it out again; no other action.
When you've got that, try to read in the string, then print it out character-by-character.
If you can do that, you're ready for step 3 and almost done.
EDIT: also, when you get there,
while(front_char != ' ')
is better than != 32; it's more reliable and much easier to read and understand.
For example, if I type in badf and space(signalling "an end", or the sentinel value for end of string)
You want to take input as string ex-badf but your are taking input in a character variable.
scanf("%c" , &first_char);
Second -
while(front_char != 32)
Checking if front_char is space or not but front_char does not have any value stored in it.
Program will crash as soon as you give input !!
Okay I have two problems with my solution to this problem, I was hoping I could get some help on. The problem itself is being able to print out #s in a specific format based on user input.
My questions are:
When I input 7, it outputs the correct solution, but when I output 8 (or higher), my buffer, for whatever reason add some garbage at the end, which I am unsure why it happens. I would add a picture but I don't have enough rep points for it :(
In my code, where I've inputted **HELPHERE**, I'm unsure why this gives me the correct solution. I'm confused because in the links I've read (on format specifiers) I thought that the 1 input (x in my case) specified how many spaces you wanted. I thought this would've made the solution x-n, as each consequent row, you'd need the space segment to decrease by 1 each time. Am I to understand that the array somehow reverses it's input into the printf statement? I'm confused because does that mean since the array increases by 1, on each subsequent iteration of the loop, it eats into the space area?
int main(void){
printf("Height: ");
int x = GetInt();
int n = 1;
int k=0;
char buff[x]; /* creates buffer where hashes will go*/
while(n<=x){ /* stops when getint value is hit*/
while(k<n) /* fill buffer on each iteration of loop with 1 more hashtag*/
{
buff[k] = '#';
k++;
}
printf("%*s",x, buff); /*makes x number of spaces ****HELPHERE*****, then prints buffer*/
printf(" ");
printf("%s\n",buff); /*prints other side of triangle */
/*printf("%*c \n",x-n, '\0');*/
n++;
}
}
Allocate enough memory and make sure the string is null terminated:
char buff[x+1];//need +1 for End of the string('\0')
memset(buff, '\0', sizeof(buff));//Must be initialized by zero
Print as many blanks as requested by blank-padding an empty string:
printf("%*s", x, "");
※the second item was written by Jonathan Leffler.
In printf("%*s",x, buff);, buff in not null character terminated.
Present code "worked" sometimes as buff was not properly terminated and the result was UB - undefined behavior. What likely happened in OP's case was that the buffer up to size 7, fortunately had '\0' in subsequent bytes, but not so when size was 8.
1) As per #BLUEPIXY, allocated a large enough buffer to accommodate the '#' and the terminating '\0' with char buff[x+1];
2) Change while loop to append the needed '\0'.
while (k<n) {
buff[k] = '#';
k++;
}
buff[k] = '\0';
3) Minor:insure x is valid.
if (x < 0) Handle_Error();
char buff[x];
4) Minor: Return a value for int main() such as return 0;.