How to assign a string to a character pointer in C? - c

How do I assign a string to a character pointer in C ?
Suppose I have a string like "1234788654446" and when I assign it to a char pointer, I am getting error like "missing terminating character". What's wrong with the following code ?
The actual problem statement is this : I have a 1000 digit number and i have to find the greatest product of 5 consecutive digits. so when i store the number in a string, I am getting warning: ""Integer constant is too large for its type" and error "Invalid digit 9 in octal constant" .
My code is :
#include<stdio.h>
int main(){
int i=0;
int a,b,c,d,e,pro,max=0;
char str[] = "73167176531330624919225119674426574742355349194934
96983520312774506326239578318016984801869478851843
85861560789112949495459501737958331952853208805511
12540698747158523863050715693290963295227443043557
66896648950445244523161731856403098711121722383113
62229893423380308135336276614282806444486645238749
30358907296290491560440772390713810515859307960866
70172427121883998797908792274921901699720888093776
65727333001053367881220235421809751254540594752243
52584907711670556013604839586446706324415722155397
53697817977846174064955149290862569321978468622482
83972241375657056057490261407972968652414535100474
82166370484403199890008895243450658541227588666881
16427171479924442928230863465674813919123162824586
17866458359124566529476545682848912883142607690042
24219022671055626321111109370544217506941658960408
07198403850962455444362981230987879927244284909188
84580156166097919133875499200524063689912560717606
05886116467109405077541002256983155200055935729725
71636269561882670428252483600823257530420752963450";
while(str[i+4] !='\0'){
a = str[i]-'0';
b = str[i+1]-'0';
c = str[i+2]-'0';
d = str[i+3]-'0';
e = str[i+4]-'0';;
pro = a*b*c*d*e;
if(pro>max)
max = pro;
i++;
}
printf("%d",max);
return 0;
}

Line breaks aren't your friend. You need to do ...
char str[] = "73167176531330624919225119674426574742355349194934\
96983520312774506326239578318016984801869478851843\
...
71636269561882670428252483600823257530420752963450";
(Notice the \ on the end of each line, and no leading whitespace on subsequent lines. You can't split a quoted string over multiple lines in C without using \)
Option B is:
char str[] = "73167176531330624919225119674426574742355349194934"
"96983520312774506326239578318016984801869478851843"
...
"71636269561882670428252483600823257530420752963450";

It looks like the problem is that you're assigning the string over multiple lines. If you're going to do that, make sure you have a \ followed by no other characters at the end every line during the string assignment so the compiler knows that the string continues below.
Alternative solutions would be to assign the string on one singular line, or wrap each line in quotes.
Example:
char str[] = "73167176531330624919225119674426574742355349194934\
96983520312774506326239578318016984801869478851843\
84580156166097919133875499200524063689912560717606\
05886116467109405077541002256983155200055935729725\
71636269561882670428252483600823257530420752963450";

You can't wrap strings like that. You can concatenate them by putting "s around each line:
char str[] = "123"
"432"
"543";
Or you can use a backslash \ to continue lines if you ensure there is no extra whitespace at the beginning.
char str[] = "123\
456\
789";
The warnings are coming because the compiler is interpreting subsequent lines as integers, which are too large to be stored. And a line of digits starting with 0 is interpreted as an octal number, which explains the "invalid digit 9" error.

Related

Why am I not getting the concatenated string?

I have written this code where I want to add two integers, two doubles and concatenate two strings out of which one of the integer, double and the string is already declared and the other integer, string and double are to be taken by the user. But it seems that the program isn't taking another string as an input.
I have written a similar program where I can take the string from the user using scanf but the same isn't working here.
int main() {
int i = 4;
double d = 4.0;
char s[] = "My college name is ";
// Declare second integer, double, and String variables.
int i2,sum1;
double d2,sum2;
char s2[100];
// Read and save an integer, double, and String to your variables.
scanf("%d",&i2);
scanf("%lf",&d2);
scanf("%[^\n]%*c",&s2);
sum1= i+i2;
sum2= d+d2;
strcat(s,s2);
// Print the sum of both integer variables on a new line.
printf("%d\n",sum1);
printf("%.1lf\n",sum2);
printf("%s",s);
return 0;}
After I made the necessary changes like removing & from s2 and changing s[] to s[200], I still cannot get the concatenated string. I am writing my edited code. Kindly help me with that.
int main() {
int i = 4;
double d = 4.0;
char s[200] = "My college name is ";
// Declare second integer, double, and String variables.
int i2,sum1;
double d2,sum2;
char s2[100];
// Read and save an integer, double, and String to your variables.
scanf("%d",&i2);
scanf("%lf",&d2);
scanf("% [^\n]%*c",s2);
sum1= i+i2;
sum2= d+d2;
strcat(s,s2);
// Print the sum of both integer variables on a new line.
printf("%d\n",sum1);
printf("%.1lf\n",sum2);
printf("%s",s);
return 0;
}
Kindly help me with the bug here.
It's not taking your string input because you use %[^\n]%*c to scan the string. which instuct the program to return after geting a newline as input. And the string got a newline form the buffer after scanning d2, and return with out taking further input.
To get rid of this you need to input a char before taking the input of the string. Change the following lines:
scanf("%lf",&d2);
scanf("%[^\n]%*c",&s2);
To:
scanf("%lf",&d2);
getchar();
scanf("%[^\n]%*c",&s2);
And your code will take the string input properly.
Additionally, you can also do this (taking a extra character input befor string input) by putting a extra space before % sign.
Changing the following line:
scanf("%[^\n]%*c",&s2);
To:
scanf(" %[^\n]%*c",&s2);
Also do the same thing.
You are passing the wrong type of argument to scanf. s2 is an array of chars, so &s2 is a pointer to an array of chars, not a pointer to a char.
(You also ought to have bounds checking to prevent array overflows, add a newline to your final printf, etc. But eliminating the & will make your program compile and run)
Possibly your use of
scanf("%[^\n]%*c",&s2);
As far as I'm aware you can use
scanf("%[^\n]%*c",s2);
or
scanf("%[^\n]%*c",&s2[0]);
As the variable s2 is itself a pointer to the first memory address of the array, using &s2 is just a pointer to a pointer and has no allocated consecutive memory addresses to fill. Hope this helps.
Replace:
scanf("%[^\n]%*c",&s2);
With:
fgetc(stdin);
fgets(s2, 100,stdin);

Printing the value of a 0-initialized array element prints nothing, why?

I have to initialize a char array to 0's. I did it like
char array[256] = {0};
I wanted to check if it worked so I tried testing it
#include <stdio.h>
int main()
{
char s[256] = {0};
printf("%c\n", s[10]);
return 0;
}
After I compile and run it, the command line output shows nothing.
What am I missing ? Perhaps I initialized the array in a wrong manner ?
TL;DR -- %c is the character representation. Use %d to see the decimal 0 value.
Related , from C11, chapter §7.21.6.1, (emphasis mine)
c If no l length modifier is present, the int argument is converted to an
unsigned char, and the resulting character is written.
FYI, see the list of printable values.
That said, for a hosted environment, int main() should be int main(void), at least to conform to the standard.
You are printing s[10] as a character (%c), and the numeric value of s[10] is 0, which represents the character \0, which means end of string and has no textual representation. For this reason you are not seeing anything.
If you want to see the numeric value instead of the character value, use %d to print it as a decimal (integer) number:
printf("%d\n", s[10]);
Note that end of string isn't the same as end of line, as said in one of your comments. End of string means that any string operation over a character sequence must stop when the first \0 arrives. If the character sequence has anything else after \0, it won't be printed, because the string operation stops on the first \0 character.
An end of line is, however, a normal character, which visual effect is to say the terminal or text editor to print the next character after the end of line in a new line.
If you want to have a vector full of end of line characters (and print them as such), you have to travel the vector and fill it:
char s[256];
int i;
for (i = 0; i < 256; ++i)
s[i] = '\n';
printf("%c\n", s[10]);
The ASCII (decimal/numerical) value of the end of line character (\n) is 12, so, the following snippet will be equivalent:
char s[256];
int i;
for (i = 0; i < 256; ++i)
s[i] = 12;
printf("%c\n", s[10]);
That doesn't work however (it doesn't print a new line):
char s[256] = {'\n'}; // or {12};
printf("%c\n", s[10]);
because the effect of {'\n'} is to assign \n to the first element of the array, and the remainings 255 character are filled with value 0, no matter which type of array are you making (char[], int[] or whatever). If you write an empty pair of brackets {}, all the elements will be 0.
So, these two statements are equivalent:
char s[256] = {}; // Implicit filling to 0.
char s[256] = {0}; // Implicit filling to 0 from the second element.
However, without defining the array:
char s[256];
The array is not filling (not initialized), so, each element of s will have anything, until you fill it with values, for example, with a for.
I hope with all of this examples you get the whole picture.

Append to C String Based on User Input

I would like to receive an integer x via user input, and return a string with length x in '#'s.
i.e.
x = 4
⇒ "####"
Is a simple solution possible, along the lines of:
printf( "%c * x = %c", hash, x, hash*x);
Currently, my online findings have me creating an iterative program:
#include <stdio.h>
#include <string.h>
//function creates xhash with width '#' characters
void append( char* xhash, char hash, int x )
{
int i = 0;
for ( i = 0; i < x; i++ ) { xhash[i] = hash; }
xhash[x] = '\0';
}
int main ( void )
{
int x = 0;
scanf( "%d", &x );
char xhash[250] = "";
char hash = "#";
append( xhash, hash, x );
printf( "%c", xhash );
return 0;
}
And this gives me a strange design: ▒
I find C strings very confusing, coming from Python where I would use
str.append(i)
or
str = "#" * x
C does not have a full-fledged string data type. "C strings" are just contiguous sequences if char values, terminated by a character with value 0 (which can be spelled '\0').
Very important to your question, though, is that (1) char is an integer data type, (2) different delimiters are used for string literals than for (single-)char literals, and (3) string literals evaluate to pointers to the first character of a C string.
Thus, this ...
char hash = "#";
... attempts to store a pointer in hash, probably resulting in the last byte of the pointer value. Instead, you want this:
char hash = '#';
Moreover, to print a C string via one of the printf()-family functions, you want to use edit descriptor %s:
printf("%s", xhash);
Descriptor %c is for outputting a single character.
A string in C is just an array of bytes followed by a zero byte. That is all that they are.
For a function that creates a string you have two options. You can have the caller pass in a pointer to an array (and the array size, if you're smart) and the function fills it in. The second option is to malloc inside your function and return the pointer to the caller.
Another thing to remember is the standard C library. Your append function is essentially memset followed by setting a zero at the end. You should just call memset instead of doing your own loop.
And I think you are getting weird output because the printf format for a string is %s not %c. The %c format is for a single character.
Finally if you are unfamiliar with C programming you should be compiling will all warnings turned on. The compiler warnings would have told you about the bad printf format string and the invalid char assignment.

Printing three strings with identical content gives different results

#include "stdio.h"
void main()
{
char firstName[1] = "1";
char middleName[1] = "1";
char lastName[1] = "1";
printf("%p\t%s\n",firstName,firstName);
printf("%p\t%s\n",middleName,middleName);
printf("%p\t%s\n",lastName,lastName);
}
I compile this code use the gcc 4.8.2, what is confusing me is why it print:
>
root#ubuntu:~# ./main
0x7fff7124273d 111
0x7fff7124273e 11
0x7fff7124273f 1
I think it should print:
0x7fff7124273d 1
0x7fff7124273e 1
0x7fff7124273f 1
Can you help me?
char firstName[1] = "1";
It's legal to initialize a char array like this, but it's not a string, because it's not null-terminated.
"%s" in printf expects a string, so what you are doing is undefined behavior.
My guess is, the compiler puts the variables together, and what byte after them happens to be 0, that can explain what happened. But again, it's undefined behavior, anything could happen.
'1' '1' '1' 0
^ ^ ^
firstName | |
middleName |
lastName
Because size of array is 1 and you are assigning the array of length 2 (string literal also have null character \0 at the end). Hence, string pointed by the pointer may not be NULL terminated string. You need array of size 2.
char firstName[2] = "1";
char middleName[2] = "1";
char lastName[2] = "1";
or
char firstName[] = "1";
char middleName[] = "1";
char lastName[] = "1";
Also, do not use void main in C. Use int main.
"1" is actually two bytes in size - '1', '\0' - you're forgetting that C strings are null-terminated. The null bytes are getting trashed by the initialization. Your arrays need to be big enough to contain all the data in the initializer to avoid this.
Remember, C-style strings are null-terminated arrays, meaning that there should be '\0' after the string. Notes that might help you:
char firstName[2] = "1"; - Adds '\0' by itself, note the 2 instead of 1.
char firstName[] = {'1'} - Does not add '\0'.
char firstName[2] = {'1'} - adds '\0'.
You're getting this output because probably the chars are put together, this is undefined behavior.
in your code
printf("%p\t%s\n",firstName,firstName);
the first thing getting printed is the base address of the array firstName,
the second thing is actually undefined behaviour. for any character array to be a string it must have null character \0 at the end. your array is only 1 character long., and containing '1'. so you acnnot use %s to print that.
instead of %s use %c to print the character, like \
printf("%p\t%c\n",firstName,firstName);
In C, strings are NUL-terminated, i.e. the string "1" is the characters {'1', 0}. You have not allowed enough room for the terminator, so your strings are truncated and printf doesn't know where they end.
It would be better to define them as
char firstName[2] = "1";
and best to do
char firstName[] = "1";
so the compiler calculates the right amount of memory for you if you should ever deal with some with a first name which is longer than 1 character.

Using atoi to fill an array of ints

First time asking a question on here. Apologies if there's already threads about this but i had a few searches and didn't quite find what i think i was looking for. I'm very new to C and am working through a few homework exercises for my microcontroller systems class. We're currently working through easy exercises before we get into embedded C and I'm trying to write a program that'll take a line of text consisting of 10 numbers separated by commas and fill an array of ints with it. As a hint we were told to use a substring and atoi. I think i'm close to getting it right but i can't get it to output my numbers properly.
Also i'm not looking spoon fed answers. A few hints would suffice for now. I'd like to try figuring it out myself before asking for the solution.
Here is my code:
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int a[10];
char str[] = {1,2,3,4,5,6,7,8,9,10}; //contains string of numbers
int i;
puts("This prints out ten numbers:");
for (i = 0; i < 10; i++)
{
a[i] = atoi(str);
printf("%d", a[i]);
//i'm guessing the problem lies in one of the above two lines
}
return 0;
}
This is outputting the following:
This prints out ten numbers:
0000000000
Thanks to anyone that can help!
Chris
You said that you have to use a line of text separated by commas but you've actually declared a char array containing ten (binary) integers. To get that into a string you just need to do this:
char str[] = "1,2,3,4,5,6,7,8,9,10";
Then you'll need someway to process this string to get each number out and into your array of int.
First off, you should declare a string as follows:
char str[] = {"1,2,3,4,5,6,7,8,9,10"};
the " made the numbers a whole string. Next, you'll need to tokenize them and using the <string.h> library which will come quite handy in this situation.
Here is how you do tokenizing:
define a token buffer first:
char* token;
token = strtok(str,","); //think of it as substring, the part of the str before the comma
for (i = 0; i < 10; i++)
{
a[i] = atoi(token);
printf("%d\t", a[i]);
//i'm guessing the problem lies in one of the above two lines
token = strtok(NULL, ","); //this line is also required for tokenizing the next element
}
Using the strtok() function, you separated the elements between the comas, and got yourself the number strings. Used atoi() function to convert them into integers and printed them. You can see this reference for strtok() function for better understanding.
The problem lies in how you're creating the string.
Please excuse my previous answer, I misunderstood your question:
Simply put, the declaration should be as follows:
char str[] = "1,2,3,4,5,6,7,8,9, 10, 12";
Next, you can use strtok to separate the string into an array of strings omittied the separator (which is in your case the comma), then pass the array members to atoi
Now, why is your code not working?
First, characters should be surrounded by the apostrophes or else the compiler will take the number you pass literally as the ASCII value.
Second, arrays in C like this:
char str[] = {'1', '2', '3', '4', '5'}; don't mean a comma separated string, these commas separate the ARRAY members, each in its own index and not as a whole string.
Your definition of char str[] = {1,2,3,4,5,6,7,8,9,10}; actually sets
the values of the chars to 1 to 10.
In the ASCII-chart of characters, these are unprintable control-characters.
Writing '1' instead of 1 will set the value to the ASCII-value of 1, which is 0x31.
another mistake is that the commas in your definition only seperate the values in the definition, so the result is a array of chars without any seperation, so 12345678910.
so the correct way would be
char str[] = "1,2,3,4,5,6,7,8,9,10";

Resources