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.
Related
The program is meant to remove the '-' from an ISBN code inputted, eg. "978-123456-789" is inputted and "978123456789" is outputted. Instead what I'm getting out is "978123456789978123456789" - it's printing it twice. Can someone please explain to me why? Thanks
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
int main(void)
{
char ISBN[16], arrayClean[12];
int i,j,k,a;
printf("Enter your ISBN: ");
scanf("%s",&ISBN);
for(i=0; i<=13; i++)
{
a = ISBN[i] - 48;
if(a==-3)
{
for(j=i;j<=13;j++)
{
k++;
ISBN[j]=ISBN[j+1];
}
k=0;
i=0;
}
}
for(i=0; i<=11; i++)
arrayClean[i]=ISBN[i];
printf("%s",arrayClean);
return 0;
}
You seem to have 12 chars in a number (excluding dashed. 14 counting them).
Your loops therefore cannot deal with chars 0 to 11 of the output, and chars 0 to 13 of the input. That is forgetting the terminal '\0' that needs to be there also, in the output, at position 12.
(If you are 100% sure there will be 12 chars, then you could solve this simply by adding arrayClean[12]=0 at the end, just before printing. But that would be a bad idea. Since it would be relying on what is typed by the user).
Also, even the declarations of your array "arrayClean" does not take into account the need for a terminal '\0'. You need 13 bytes to hold a 12 characters string.
Some other remarks:
Your usage of scanf("%s", &ISBN); is dangerous.
First of all, it should be scanf("%s", ISBN);. What you need to pass scanf is the address where to store what it reads. When you are reading a single int x;, then, indeed, you should scanf("%d", &x);, to have scanf store the result at the address where x is stored. But for a string, ISBN is already an address (the address of chars ISBN[0], ISBN[1], ...). So you should not pass the address of ISBN.
What saves you here, is that since ISBN is not a variable (it is an array, that is a constant pointer), in C &ISBN and ISBN are the same thing in this very context. So, it happens to work by accident.
But if ISBN were a variable (a char * allocated with malloc for example), then this usage would lead to memory errors. So, you should take the habit of not passing &ISBN to scanf but ISBN.
Other problem with that same line: when scaning, you cannot trust the user to type the exact number of bytes you expect them to. Here, if the user types 16 or more bytes, those byte will be written to whatever memory is after the 16 bytes of ISBN. Which will cause very serious problem. Even security ones if the user does this on purpose to overwrite other variables and even codes on some architecture.
So, rule of thumb: never ever scanf("%s", ...).
Always enforce a limit to the number of bytes scanf can read. scanf("%15s", ...) for example.
You are not null terminating the string. You are only copying 12 characters from ISBN to arrayClean. You need to add a null terminator to the end of arrayClean. You can do this by adding arrayClean[12] = '\0'; after the for loop.
char ISBN[16], arrayClean[12];
int i, j, k, a;
printf("Enter your ISBN: ");
scanf("%s", &ISBN);
for (i = 0; i <= 13; i++)
{
a = ISBN[i] - 48;
if (a == -3)
{
for (j = i; j <= 13; j++)
{
k++;
ISBN[j] = ISBN[j + 1];
}
k = 0;
i = 0;
}
}
for (i = 0; i <= 11; i++)
arrayClean[i] = ISBN[i];
arrayClean[12] = '\0';
printf("%s", arrayClean);
This is my homework assignment:
And this is my code:
#include <stdio.h>
int main() {
char v[2] = {'A', 'I'};
char c[3] = {'n', 's', 't'};
int i;
for (i = 0; i < c[i]; i++) {
printf("%d %d %d %d %d %d", c[6]);
for (i = 0; i < v[i]; i++) {
printf("%d %d", v[2]);
}
}
return 0;
}
It seems to go on forever and I don't know what to do. Keep in mind that I am new to C, so I tried my best.
it seems you want to write the first letter of v[] combined with each letter of c[]
Then write the second letter of v[] combined with each letter of c[]
This hints the first/outer loop would be stepping through the array v[]
This hints the second/inner loop would be stepping through the array c[]
This hints within the inner loop would be outputting the current letter from v[] followed by the current letter from c[] followed by a space.
remembering that / (divide) has a higher precedence than < see C precedence table:
(remembering that sizeof() returns the number of characters in an object so obtaining the number of entries in an array is the total size of the array, in characters, divided by the number of characters in the first element of the array)
how to step through array v[]:
for( int i=0; i < sizeof(v) / sizeof(v[0]); i++ )
how to step though array c[]:
for( int j=0; j < sizeof(c) / sizeof(c[0]); j++ )
within the inner loop to print the current entry in v[] followed by the current entry in c[] followed by a space:
printf( "%c%c ", v[i], c[j] )
of course the above call to printf() places everything into the stdout I/O stream buffer and you actually want to display the output on the terminal, so after the nested loops exit, suggest:
printf( "\n" );
which is one way to flush the stdout buffer to the terminal.
Of course, all the above needs to be in a main() function
Of course, to use printf() need to include the header file: stdio.h
If you need clarification on any of the details, post a comment to this answer.
regarding:
printf("%d %d %d %d %d %d", c[6]);
the number of `output format conversion specifiers must match the number of values to be output. In the current statement, 6 output specifiers does not match one value to be output.
Also, the c[] array only has 3 elements and C is zero based, so the only valid indexes are 0..2, not 6. Accessing index 6 results in accessing beyond the end of the array, which results in undefined behavior.
so in my CS course we have to make a calculator which reads input and then calculates the result after the = sign has been read.
Input always consists of one number followed by operator.
I'm now struggling with the way of scanning the input. I want to use some loop which would always store it like:
scanf("%lf %s ", &in, c);
Note: the calculator goes one operation after other. Thus in example below the plus sign works only for 20 and 4, and only then the result takes the division sign and gets divided by 8. Then the new result gets negated by 'neg' string.
E.g.: Input: 20 + 4 / 8 neg =
Output: Result: -3
This is how I tried to solve it. My intention was to make the loop store each number into a new "box" of array, and then to store each string into the new "line" of char array. The 4 in op array is meant to set the max length of the string, because i know that the longest string that can occur is "sqrt".
I see that the '\n' in the condition of for is probably useless but can't figure out how to do it...
I'm thinking about using either for, or a while loop.
int main(){
double in[10];
char op[5][4];
for(int i=0; i<5;i++){
scanf("%lf %s ", &in[i], op[i][4]);
}
printf("%.3f %s", in[0], op[0][0]);
return 0;
}
//just a "skeleton" of the code. There's more to it, but here I submitted just the part that I'm struggling with.
For example if I run this code, I want to write a few numbers followed by operator into the input.
I expect it to print the first number and string (just to check whether the loop works).
But actually it does absolutely nothing and just gives me some large negative number as a return.
From the man page of scanf
int scanf(const char *format, ...);
as you can see first argument is of const char * type i.e you need to provide valid address.
With this
char op[5][4]; /* 5 char array, in each char array you can have 4 char's
* i.e op[row][0] to op[row][3]. There is no op[i][4]
*/
you can have
for(int i=0; i<5;i++){
scanf("%s",op[i]); /* op[i] itself address, so don't need & */
}
or
for(int i=0; i<5;i++){
for(int j=0; j<4; j++) {
scanf(" %c", &op[i][j]); /* storing char by char */
}
}
Also while printing here use %c as op[0][0] is of char type.
printf("%.3f %c", in[0], op[0][0]);
In a scanf format string, %s indicates you want to read a string, meaning it needs the address of where to put that string. You are passing op[i][4] for it, which is a char.
I have the following code which I am trying to run.
I want the scanf function to take in three different inputs, with the first two being integers between 0 and 30, and the third a string beginning with #.
The program compiles fine, but when I attempt to input the coordinates and the associated #symbol, I get a 0 in the y coordinate's place.
Does anyone know why this is happening or what I can do to fix it?
Below is the code
#include <stdio.h>
int main(){
int grid[30][30];
int i, j;
for(i=0; i<30;i++){
for(j=0; j<30;j++){
grid[i][j]='.';
}
}
int x_coord;
int y_coord;
char type[2];
scanf("%d %d %s",&x_coord,&y_coord,type);
/*added extra whitespace*/
printf("%i %i %s",x_coord,y_coord,type);
printf("\n");
grid[x_coord][y_coord]=type[1];
//end outer loop
for(i=0; i<30;i++){
for(j=0; j<30;j++){
printf("%c",grid[i][j]);
}
printf("\n");
}
return(0);
}//end main
As you declared char type[2]; and you are first entering # and then new character suppose X so in type it will go like this
type[0] = #
type [1]='\0'
so you should declare char type[3]; this way
so that
type[0] = #
type [1]='X'
type [2]='\0'
it will stored this way and you can get X by accessing type [1]
Assuming you are entrering #X for the string, where X is some single character, scanf is going to attempt to fill type with '#' 'X' and '\0' (null byte added by scanf to mark the end of the string)
That's 3 bytes being stored in array that is only big enough for two.
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".