I want to give the program an integer value from 1 to 26 (doesn't need to be hardcoded) that creates a char Array that is filled with the letters from A to letter n.
This is the code:
int main(int argc, char *argv[])
{
int n = atoi(argv[1]);
char comb[n];
for (int i = 0; i < n; i++)
comb[i] = 65 + i;
printf("%s", comb);
}
The problem is, that if i hand over values from 8 - 15 and 24 - 26, the output shows something like this:
ABCDEFGH�������
However, if i hardcode n to be one of the problematic values from above, the output is just right.
Can somebody explain to me, why the program puts out the extra �.
Thanks
The standard way to convert a string to a numeric type in C is to use the strto* family of functions. In your case, you would want something like:
int count = strtol(argv[1], // String
NULL, // Optional output pointer to where the scan stopped
10) // Radix
I'd also check that argc > 2, i.e. that argv[1] was actually passed by the user.
%s expects a pointer to a null terminated string. In other words, printf has no way of knowing where the string argument stops until it sees the '\0', so what you're seeing is some other part of your process memory being printed out as text. To fix: allocate n + 1 for comb, and memset(comb, n + 1, 0); before the loop, or set comb[n] = '\0' right after the loop.
Related
I am new to C programming and trying to make a program to add up the digits from the input like this:
input = 12345 <= 5 digit
output = 15 <= add up digit
I try to convert the char index to int but it dosent seems to work! Can anyone help?
Here's my code:
#include <stdio.h>
#include <string.h>
int main(){
char nilai[5];
int j,length,nilai_asli=0,i;
printf("nilai: ");
scanf("%s",&nilai);
length = strlen(nilai);
for(i=0; i<length; i++){
int nilai1 = nilai[i];
printf("%d",nilai1);
}
}
Output:
nilai: 12345
4950515253
You have two problems with the code you show.
First lets talk about the problem you ask about... You display the encoded character value. All characters in C are encoded in one way or another. The most common encoding scheme is called ASCII where the digits are encoded with '0' starting at 48 up to '9' at 57.
Using this knowledge it should be quite easy to figure out a way to convert a digit character to the integer value of the digit: Subtract the character '0'. As in
int nilai1 = nilai[i] - '0'; // "Convert" digit character to its integer value
Now for the second problem: Strings in C are really called null-terminated byte strings. That null-terminated bit is quite important, and all strings functions (like strlen) will look for that to know when the string ends.
When you input five character for the scanf call, the scanf function will write the null-terminator on the sixth position in the five-element array. That is out of bounds and leads to undefined behavior.
You can solve this by either making the array longer, or by telling scanf not to write more characters into the array than it can actually fit:
scanf("%4s", nilai); // Read at most four characters
// which will fit with the terminator in a five-element array
First of all, your buffer isn't big enough. String input is null-terminated, so if you want to read in your output 12345 of 5 numbers, you need a buffer of at least 6 chars:
char nilai[6];
And if your input is bigger than 5 chars, then your buffer has to be bigger, too.
But the problem with adding up the digits is that you're not actually adding up anything. You're just assigning to int nilai1 over and over and discarding the result. Instead, put int nilai1 before the loop and increase it in the loop. Also, to convert from a char to the int it represents, subtract '0'. All in all this part should look like this:
int nilai1 = 0;
for (i = 0; i < length; i++) {
nilai1 += nilai[i] - '0';
}
printf("%d\n", nilai1);
For starters according to the C Standard the function main without parameters shall be declared like
int main( void )
This character array
char nilai[5];
can not contain a string with 5 digits. Declare the array with at least one more character to store the terminating zero of a string.
char nilai[6];
In the call of scanf
scanf("%s",&nilai);
remove the operator & before the name nilai. And such a call is unsafe. You could use for example the standard function fgets.
This call
length = strlen(nilai);
is redundant and moreover the variable length should be declared having the type size_t.
This loop
for(i=0; i<length; i++){
int nilai1 = nilai[i];
printf("%d",nilai1);
}
entirely does not make sense.
The program can look the following way
#include <stdio.h>
#include <ctype.h>
int main(void)
{
enum { N = 6 };
char nilai[N];
printf( "nilai: ");
fgets( nilai, sizeof( nilai ), stdin );
int nilai1 = 0;
for ( const char *p = nilai; *p != '\0'; ++p )
{
if ( isdigit( ( unsigned char ) *p ) ) nilai1 += *p - '0';
}
printf( "%d\n", nilai1 );
return 0;
}
Its output might look like
nilai: 12345
15
my program is taking an argument which says how many prints that should be used.
example of arguments: prints 2.
I then want to loop through the value after prints, the number 2. and then print that many times. I tried like this:
for(i = 0; i < argv[2]; i++)
{
....
The problem is that argv is a char and i is an int. So when I run this loop, argv[2] aquire the value: 123123123 or something, instead of just 2. Is there any way around this or to compare the value in a char with an int. Thanks in advance
argv[2] is a char* not a char. argv[2] points to a string( array of null terminated characters ). When you pass an arguments to you program, the argument is in that form.
You will have to convert it, you can use atoi() ;
argv[2] is char*, is string in C language, if you want to change it to int, you must
convert it. Convert String to int.
Here is an example:
int atoi(char *str){//Just suit for int
int ans = 0,i=0;
while(str[i]){
ans = ans*10 + (str[i]-'0');
i++;
}
return ans;
}
You can call it like this atoi(argv[2]);
int n = argv[i][j];
n = n + (int)argv[1];
/* I'm pretty sure the above part that is wrong. What I was hoping that this
would do is take the number the person put in and increase n by that number but
it isnt working*/
printf("%d\n", n);
i = the string numbers of the argument
j = the characters of the string
What I want is to make it so when someone types ./123 12 hi I want it to increase the ascii characters of h and i by 12 or whatever number they put in. When I test my code out with
./123 1 hi
I get an output of
-1081510229
-1081510228
instead of
105
106
which is i and j, the next letters of h and i
Libraries I'm using
stdio.h
studio50.h
string.h
argv[1] is a string (i.e, a null-terminated char array), casting it to int doesn't give the result you expected
You should use atoi to do the job. Or better, use strtol to get better stability.
I am new to C and I am currently trying to get a substring of a string. The eventual goal is I have a string, which contains a set of numbers, i.e. 6218, and I keep taking a substring so I remove the last number, i.e.:
6218
621
62
6
At the moment I am hard coding the length I want to be, so as a start I am doing a substring of 4, expecting the result to still be 6218. However, its coming out at 62 when I print it in gdb.
Below is the code I am using.
char * performSearch(char * phoneNumber, int totalLookupNumberCount, numberLookupStruct *numberLookup, int maxCharsToLookup)
{
int i;
for (i = strlen(phoneNumber); i < maxCharsToLookup; i--)
{
char searchNumber[i+1];
strncpy(searchNumber, phoneNumber, 4);
searchNumber[i+1] = '\0';
}
}
The function is called by the following:
char * displayName = performSearch(phoneNumber, totalLookupNumberCount, numberLookup, maxCharsToLookup);
I am stepping through the code in GDB so the very first thing I do, is print the searchNumber after the strncpy, therefore the loop doesn't actually get used.
I've checked the variables passed through and what strlen is returning and its correct
So in the code above I am expecting searchNumber to still be 6218, but it is outputting 62. Also just to be aware phoneNumber is passed to the function as char *.
Thanks for any help you can provide.
The for test condition seems wrong:
for (i = strlen(phoneNumber); i < maxCharsToLookup; i--)
If maxCharsToLookup is larger than strlen(phoneNumber), then it seems like this loop will do something funky when i becomes negative. If maxCharsToLookup is less than or equal to strlen(phoneNumber), then the loop never starts. Probably you need something like this:
for (count = 0, i = strlen(phoneNumber);
count < maxCharsToLookup && i > 0;
++count, --i)
strncpy() is hard to use. It will only NUL terminate the destination string if the source string has a shorter string length than the specified copy length. This is a hard rule to remember. In addition, it will always write the number of bytes you specified to write in the last parameter. In your code:
char searchNumber[i+1];
strncpy(searchNumber, phoneNumber, 4);
searchNumber[i+1] = '\0';
If i is less than 3, strncpy() will overrun your buffer. This will lead to undefined behavior. You then set the byte after your buffer to NUL, which is also undefined. You should do something like this instead:
char searchNumber[i+1];
strncpy(searchNumber, phoneNumber, i);
searchNumber[i] = '\0';
I prefer to use snprintf(). It always NUL terminates the resulting string.
#include <stdio.h>
#include <string.h>
int main () {
char phoneNumber[] = "6218";
for (int i = strlen(phoneNumber); i > 0; --i) {
char searchNumber[i+1];
snprintf(searchNumber, sizeof(searchNumber), "%s", phoneNumber);
puts(searchNumber);
}
return 0;
}
Just do
string[i]=0;
This will put an end-of-string character just after the specified point, cutting off the rest of the string.
In C, I want to check a given array of chars for an arbitrary letter, and change it according to what it is. For example, the characters "a" or "A" would be changed to "4"(the character representing 4). This is a coding excercise for me :)
The code is as follows:
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <zlib.h>
#define NUM_BUFFERS 8
#define BUFFER_LENGTH 1024
char buffArrays[NUM_BUFFERS][BUFFER_LENGTH];
int main(int argc, const char* arg[v])
{
const char a[] = "a";
gzFile file;
file = gzopen("a.txt", "rb"); //contains 8 lines of 1024 'a's
int counter = 0;
while(counter < NUM_BUFFERS)
{
gzread(file, buffArrays[counter], BUFFER_LENGTH - 1);
counter++;
}
counter = 0;
while(counter < NUM_BUFFERS)
{
int i = 0;
for( i; i < BUFFER_LENGTH; i++ )
{
int *changed = &buffArrays[counter][i];
if( memcmp(&a, changed, 1) == 0 )
printf("SUCCESS\n");
}
counter++;
}
gzclose(file);
return 0;
}
This code never reaches the "SUCCESS" part. This says to me that either
(1) the value of changed is not pointing to the correct thing
(2) the pointer &a is incorrect
(3) I am completely wrong and it is something else
Any help would be appreciated.
Two things.
The following assigns the value 0x61 or 'a' to the character string.
const char a[] = 'a';
You probably rather meant to write
const char a = 'a'; /* assign a character to a character */
or
const char a[] = "a"; /* assign a string to a string */
The next thing is with the following statement. Hereby you assign a pointer to an int with the memory address of a char. Which invokes undefined behavior as you are reading over the bounds of your valid memory in the next statement.
int *changed = &bufferArrays[counter][i];
Hereby you compare the first four bytes starting from both addresses. Both variables are only one byte wide.
if( memcmp(&a, changed, 4) == 0 )
If you only want to know whether there is an 'a' in some of your buffer, why don't you just.
int i, j;
for (i = 0; i < NUM_BUFFERS; i++)
for (j = 0; j < BUFFER_LENGTH; j++)
if (bufferArrays[i][j] == 'a') printf("got it!\n");
This:
bufferArrays[counter] = "a"; //all the buffers contain one "a"
is wrong, since bufferArrays[counter] is not a character pointer but a character array. You need:
strcpy(bufferArrays[counter], "a");
Also, you don't show readTOmodify, so that part is a bit hard to understand.
Further, strings are best compared with strcpy(), which compares character-by-character and stops at the terminating '\0'. You use memcmp(), and I don't understand the reason for the 4 which is the number of bytes you're comparing.
1) bufferArrays[counter] = "a"; //all the buffers contain one "a"
This is not ok, you have to use strcpy to copy strings:
strcpy(bufferArrays[counter],"a"); //all the buffers contain one "a"
2)
#define BUFFER_LENGTH 1
Here's a problem. Buffer length should be at least 2 if you want to store just one char (for the extra null-termination).
3) In both of your loops, you never change counter, which leads to infinite loop.
Where's your code? I don't see any function surrounding it.
EDIT:
To assign you can also use:
while(counter < NUM_BUFFERS)
{
bufferArrays[counter][0] = 'a'; //all the buffers contain one "a"
counter++;
}
In any case, you have to have Buffer length as 2 if you want use it as a C-string.
The statement
bufferArrays[counter] = "a";
is not legal. It assigns a pointer to a single char and should give a compiler error (or at least a warning). Instead try
bufferArrays[counter] = 'a';
Also, in the while loops (both of them) you do not increase counter and so loop over the same index over and over forever.
Edit: Further problems
The condition where you do the comparison is flawed as well:
memcmp(&a, changed, 4)
The above doesn't compare pointers, it compares the contents of what the pointers point to, and you compare four bytes while the contents is only a single byte. Besides, you can't compare the pointers, as they will be different; The contents of the variable a is stored at a different location than that of the contents of bufferArrays[counter][i].