Storing first characters of elements in a string [closed] - c

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 4 years ago.
Improve this question
How can I store the first character of an element in a string? E.g. if I run
for (j=0; j < 5; j++) {
printf("%s\n, string[j]);
}
I get
hello
how
are
you
Thanks to the answer provided by #Holy semicolon, I know that I can run printf("%c\n, string[j][0]); to print the first letters:
h
h
a
y
However, how can I store the first letters in a new array?
So far, I have:
char secondStr[10];
for (j=0; j<5; j++) {
secondStr[j] = string[j][0];
}
This results in an error assignment makes pointer from integer without a cast
I know this question is slightly different to the one I asked before (regarding printing the first elements) - I was unsure whether or not to ask an entirely new question on SO. I apologise in advance if I was supposed to ask a new question.

when you have an array of pointers to char *string1[] = {"hello", "how", "are", "you"}; and you want to print the first string of it hello so you must use %s for string like this printf("%s",string1[0]) but if you want to print the first char of the first string you need to use %c like this printf("%c",string1[0][0]).
#include <stdio.h>
int main()
{
char *string1[] = {"hello", "how", "are", "you"};
printf("%s",string1[0][0]); // I think you did this fault It'll give you Segmentation fault
return 0;
}
so as you see in the code above you need to replce %s with %c.
Edit
What if I wanted to store the first letters in a new list?
you will need then to allocate memory to the new string.
#include <stdio.h>
#include <stdlib.h>
int main()
{
char *string1[] = {"hello", "how", "are", "you"};
char **keep = calloc(sizeof(char*),5); //memory allocating
for (int index = 0; index <= 3; index++)
{
keep[index] = calloc(sizeof(char),2); //memory allocating
keep[index][0] = string1[index][0];
keep[index][1] = '\0';
}
//for test
for (int i = 0; i <= 3; i++)
printf("%c\n",keep[i][0]);
return 0;
}

If string is std::string, then:
string s[6] = { "hello","how", "are", "you", "?" };
for (int j = 0; j < 5; j++)
{
if(s[j].size())
printf("%c\n", s[j].c_str()[0]);
}
Should word.

Many options are there. I will just mention some.
Use begin()
for( int i = 0 ; i < num ; i++ )
{
string:: iterator it = String[i].begin();
cout << *it;
}
Use front()
for( int i = 0 ; i < num ; i++ )
{
cout << String[i].front();
}
Use at()
for( int i = 0 ; i < num ; i++ )
{
cout << String[i].at();
}
You can just go through the member functions of string and use it to your purpose

Related

Segmentation fault with concatenation of two strings

I'm trying to build alphanumeric strings consisting of 3 initial letters and 3 final numbers and save them in a .txt file. I wrote this:
int i = 0,
j = 0;
char name_cpu[8],
array_numbers_final[8],
array_letters[27] = "ABCDEFGHIJKLMNOPQRSTUWXYVZ",
array_numbers[10] = "123456789";
/* Generator data */
for(i = 0; i < number_cpu; i++)
{
for(j = 0; j < 3; j++){
name_cpu[j] = array_letters[rand() % (sizeof(array_letters)-1)];
array_numbers_final[j] = array_numbers[rand() % (sizeof(array_numbers)-1)];
}
strcat(name_cpu, array_numbers_final);
fprintf(list_cpu, "%s \n", name_cpu);
}
The problem is that at the first external for loop it correctly prints a string of the form "AAA000". At the second for loop it goes in segmentation fault. Can anyone tell me what and where I am doing wrong?
EDIT:
A minimal reproducible example is:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main (void){
FILE *list_cpu = NULL;
int i = 0,
number_cpu = 3,
j = 0;
char name_cpu[8] = {0},
array_numbers_final[8] = {0},
array_letters[27] = "ABCDEFGHIJKLMNOPQRSTUWXYVZ",
array_numbers[10] = "123456789";
list_cpu = fopen("list_cpu.txt", "w");
/* Generator data */
for(i = 0; i < number_cpu; i++)
{
for(j = 0; j < 3; j++){
name_cpu[j] = array_letters[rand() % (sizeof(array_letters)-1)];
array_numbers_final[j] = array_numbers[rand() % (sizeof(array_numbers)-1)];
}
strcat(name_cpu, array_numbers_final);
fprintf(list_cpu, "%s \n", name_cpu);
}
fclose(list_cpu);
return(0);
}
If number_cpu is equal to 1 it works. But if it is higher then 1, the program goes into segmentation fault.
answer to new edits to OP
Edits to OP include initialization of variables addressing some instances of undefined behavior in original code, however buffer overflow problem remains in following section:
/* Generator data */
for(i = 0; i < number_cpu; i++)
{
for(j = 0; j < 3; j++){
name_cpu[j] = array_letters[rand() % (sizeof(array_letters)-1)];
array_numbers_final[j] = array_numbers[rand() % (sizeof(array_numbers)-1)];
}
strcat(name_cpu, array_numbers_final);
fprintf(list_cpu, "%s \n", name_cpu);
}
fclose(list_cpu);
Where name_cpu is defined with 8 char: char name_cpu[8] = {0}
"If number_cpu is equal to 1 it works. But if it is higher then 1, the program goes into segmentation fault."...
After first iteration of outer loop, including one strcat of name_cpu and list_cpu, the char name_cpu is populated with 6 new characters and \0 in remaining locations. Eg:
//example
|S|J|P|Y|E|P|\0|\0| //
The error occurs at end of 2nd iteration of outer loop at the strcat() statement. The inner loop re-populated the first three positions of name_cpu, eg:
//first three positions changed, the rest remains
|C|B|A|Y|E|P|\0|\0| //
^ ^ ^ updated values
Error occurs when the new value for array_numbers_final :
|G|H|O|\0|\0|\0|\0|\0|
is attempted to be concatenated to name_cpu, resulting in:
|C|B|A|Y|E|P|G|H|O| //attempt to write to memory not owned
^end of buffer
Resulting in buffer overflow error, and likely the segmentation fault error condition.
Again, as before, design variables to meet the potential needs of of the program. In this instance the following will work:
char name_cpu[100] = {0};
char array_numbers_final[100] = {0};
answer to original post:
The problem is here:
strcat(name_cpu, array_numbers_final);//undefined behavior.
First, name_cpu[8] is uninitialized at time of declaration, nor is it initialized at any time before used. Because it is not guaranteed what the contents are, it is not necessarily a string. Using this variable as is in any string function can invoke undefined behavior
Furthermore,(even if name_cpu is a valid string) when array_numbers_final is concatenated to name_cpu, the buffer will overflow. During my test run I saw this:
The fix is to start off with initialized buffers of sufficient size for intended purpose. eg:
char name_cpu[100] = {0}
array_numbers_final[100] = {0},
array_letters[27] = "ABCDEFGHIJKLMNOPQRSTUWXYVZ",
array_numbers[10] = "123456789";
Code example below is adaptation using your provided example, with suggested edits. Read in-line comments:
int main(void)
{
int number_cpu = 3;//added - previously not defined in OP
int i = 0,
j = 0;
char name_cpu[100] = {0},//resized and initialize
array_numbers_final[100] = {0},//resized and initialize
array_letters[27] = "ABCDEFGHIJKLMNOPQRSTUWXYVZ",
array_numbers[10] = "123456789";
/* Generator data */
for(i = 0; i < number_cpu; i++)
{
for(j = 0; j < 3; j++){
name_cpu[j] = array_letters[rand() % (sizeof(array_letters)-1)];
array_numbers_final[j] = array_numbers[rand() % (sizeof(array_numbers)-1)];
}
strcat(name_cpu, array_numbers_final);
fprintf(stdout, "%s \n", name_cpu);//to stdout
// ^ changed here
}
return 0;
}

How to add space between every characters using C

I want a space between every character of a string like I will give input "HELLO"
the result will be "H E L L O"
I need help in that
[Edit from comments]
I want it in a string
for (i = 0; i <= strlen(str); i++) {
printf("\n String is: %s", str[i]);
printf(" ");
}
The shorter, more general answer is that you need to bump characters back, and insert a ' ' in between them. What have you done so far? Does it need to be in place?
One (perhaps not optimal, but easy to follow solution) would be making a larger array, copying in alternating letters, something like (not guaranteed to work verbatim)
char foo[N]; // assuming this has N characters and you want to add a space in between all of them.
char bar[2*N];
for (int i = 0; i < N; i++) {
bar[2*i] = foo[i];
if (i != N - 1)
bar[2*i + 1] = ' ';
}
Of course, this new string is in bar, but functions as desired. At what point are you having issues?
try this
#include <stdio.h>
void add_spaces(char need_to_add[])
{
int len = strlen(need_to_add);
char with_spaces[len*2];
int space_index = 0;
for (int i=0 ; i<len ; i++)
{
with_spaces[space_index]=need_to_add[i];
with_spaces[++space_index]=' ';
space_index=space_index+1;
}
printf("%s\n", with_spaces);
}
int main()
{
char * a = "aaa";
add_spaces(a); // fraught with problems
return 1;
}

Concatenating uint8_t to a char*

im really new to C and im having a bit of a complication creating a char* from various uint8_t
My idea is to create a char* where in each location I place a number form a matrix
For example if I have a matrix with:
[1][2][3][4]
[5][6][7][8]
[9][0][1][2]
[3][4][5][6]
id like a char* thats "01234567890123456"
what im doing bit its not working is:
char* string = malloc(sizeof(char)*matrix->height*matrix->width);
for (int i = 0; i < matrix->height ; ++i) {
for (int j = 0; j < matrix->width ; ++j) {
string[i*matrix->height+j] = matrix->value[i][j];
}
}
of course its not working but im a bit lost on how to proceed and I cant find more information regarding this problem.
Any help would be nice,
thanks
Since you're trying to print a string, you need the ASCII character for 0. So, simply add '0' to each number, like so
char* string = malloc(sizeof(char)*(matrix->height*matrix->width + 1));
for (int i = 0; i < matrix->height ; ++i) {
for (int j = 0; j < matrix->width ; ++j) {
string[i*matrix->width+j] = matrix->value[i][j] + '0';
}
}
string[matrix->height*matrix->width] = 0; //null terminator
Note however this isn't exactly the most portable solution.
Also, notice that you want to multiply i by the width, because if you didn't have a square matrix your calculation wouldn't work correctly.
It's kind of unnecessary to have sizeof(char), because the size of a char is defined to be 1 regardless of the byte size.

Segmentation Fault:11 in C [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I am writing a program in C that replaces a number in a char* called "template" with a string, but I continually get a Segmentation Fault: 11 error.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
char *rep_str(const char *s, const char *old, const char *new1){
char *ret;
int i, count = 0;
int newlen = strlen(new1);
int oldlen = strlen(old);
for (i = 0; s[i] != '\0'; i++){
if (strstr(&s[i], old) == &s[i]){
count++;
i += oldlen - 1;
}
}
ret = (char*)malloc(i + count * (newlen - oldlen));
if (ret == NULL)
exit(EXIT_FAILURE);
i = 0;
while (*s){
if (strstr(s, old) == s){ //compare the substring with the newstring
strcpy(&ret[i], new1);
i += newlen; //adding newlength to the new string
s += oldlen;//adding the same old length the old string
} else {
ret[i++] = *s++;
}
}
ret[i] = '\0';
return ret;
}
char* madlib_by_numbers(char* temp, int word_count, char* words[]){
char* numbers[] = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9"};
int tempSize = strlen(temp);
for (int i = 0; i < tempSize; i++){
if (isdigit(temp[i])){
for (int j = 0; j < (sizeof(numbers) / sizeof(char*)); j++){
temp = rep_str(temp, numbers[j], words[j]); //it makes it to this line, but never gets to assert()
}
}
}
return temp;
}
int main() {
char* temp1 = "The 1 0 likes to 2 in the moonlight.";
char* words[] = {"git", "brilliant", "swim"};
char* result = "The brilliant git likes to swim in the moonlight.";
int stringLength = strlen(result);
char* test = madlib_by_numbers(temp1, 3, words);
assert(strncmp(test, result, stringLength) == 0);
free(test);
return 0;
}
and when I run the debugger, it simply says: Segmentation Fault: 11
What i just want to understand is where the segmentation fault error is coming from, I have the suspicion one of my loops is running too many times.
There are a few issue with your code. However, the direct answer to your question is in this loop:
for (int j = 0; j < (sizeof(numbers) / sizeof(char*)); j++){
temp = rep_str(temp, numbers[j], words[j]);
}
You are calling rep_str for every digit while you mean call rep_str only if the digit in temp matches the corresponding digit in numbers. So add this conditional if(strcmp(temp,numbers[j]) == 0) right before the line temp=.... Then it'll solve your current problem.
The segfault is caused because there are only three elements in the words array. Your old loop indexes from 0 to 9 and fails when j=3, out of bound.
Also, delete the free() at the end of your program. test was never allocated and will cause a core dump.
ret = (char*)malloc(i + count * (newlen - oldlen));
There are a few problems with this line of code.
For a start, don't cast malloc (or any void * that you're assigning to a variable of different pointer type, or vice versa).
If you intended to allocate space to store a string, where's the string-terminating '\0' going to go? You need to realise that for an empty old string, this will be malloc(0) and zero bytes is not enough to store an empty string.
There's also a problem if you expect that old may be a substring of new (for example, you're replacing "0" with "hell0"). You'll need to tweak your algorithm to handle this problem. I'll leave that as a challenge for you to attempt :)
for (int i = 0; i < tempSize; i++){
if (isdigit(temp[i])){
for (int j = 0; j < (sizeof(numbers) / sizeof(char*)); j++){
temp = rep_str(temp, numbers[j], words[j]); //it makes it to this line, but never gets to assert()
}
}
}
users previous answer highlighted this code correctly, but not for the right reason... and so the solution he/she presented is wrong.
isdigit(temp[i]) may also cause segfaults for some inputs. I recommend using isdigit((unsigned char) temp[i]) instead, in this case.
It's not valid to access words[j] where word_count is 3 and j is greater or equal to 3; you're accessing that array out of bounds.
You also need to be careful to free any memory you *alloc (while simultaneously not freeing memory that you don't *alloc). Forgetting to do the former won't cause crashes, but your program won't run happily; it'll use heaps of memory.
Consider something like this, instead:
temp = strdup(temp);
if (temp == NULL) {
exit(EXIT_FAILURE);
}
for (int i = 0; i < tempSize; i++){
if (isdigit((unsigned char) temp[i])){
for (int i = min(word_count, sizeof(numbers) / sizeof(char*)), j = 0; j < i; j++){
char *new = rep_str(temp, numbers[j], words[j]);
free(temp);
temp = new;
}
}
}

Problems with creating a function to reverse a string [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Closed 7 years ago.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Improve this question
I need to create a fuction that returns a string. So far I have come up with this code:
#include <stdio.h>
#include <string.h>
#define SIZE 256
void str_reverse(char[SIZE], char[SIZE]);
int main(void)
{
char input[SIZE];
char output[SIZE];
printf("Please enter a string\n");
fgets(input, SIZE, stdin);
str_reverse(input, output);
printf("%s \n", output);
return 0;
}
void str_reverse(char in[SIZE], char out[SIZE])
{
int i = strlen(in);
int k = 0;
for(int j = i; j>= 0; j--)
{
out[k] = in[j];
k++;
}
}
However, whenever I try to run the code, I do not get an output. Does anyone have any idea what could be wrong
The problem is this line
int i = strlen(in);
Change it to
int i = strlen(in)-1;
strlen() returns the size of the string, hence when you start copying from in[], in[j] would be \0. which is getting stored in out[0].
Another change you need to do is put a \0 in the out[], just after the for loop
for(int j = i; j>= 0; j--)
{
out[k] = in[j];
k++;
}
out[k] = '\0';
Your "reversing" includes the null character too. So the reversed string's first character is '\0'. So the string is empty.
Change:
for(int j = i ; j>= 0; j--)
to
for(int j = i - 1; j>= 0; j--)
You should also check if the string length is zero before the for loop. Otherwise, i-1 will become SIZE_MAX and you'll have problems with that!
A simple condition such as the following in str_reverse() would handle that case:
size_t i = strlen(in);
int k = 0;
if (i<=1) return; //empty string or contains only 1 char char.
i starts out at strlen(in), so the first character you copy over tooutis the null byte at the end of the string. Every other character then appears after the null terminator, soout` is an empty string.
Start with i at strlen(in) - 1, then add the null terminator and the end of the loop:
int i = strlen(in) - 1; // start at the last non-null character
int k = 0;
for(int j = i; j>= 0; j--)
{
out[k] = in[j];
k++;
}
out[k] = '\0'; // add the null terminator
When k is 0 and j is i, you do the following:
out[0] = '\0';
Hence, out looks like an empty string when the function returns.
Use:
for(int j = i-1; j>= 0; j--)
{
out[k] = in[j];
k++;
}
out[k] = '\0';
In the function variable i is set the following way
int i = strlen(in);
So within the loop
for(int j = i; j>= 0; j--)
{
out[k] = in[j];
k++;
}
then j is equal to i then in[j] is equal to the terminating zero '\0' of string in. Thus array out starts from zero that is it will contain an empty string.
It is better to declare the function itself the following way
char * str_reverse( char *out, const char *in );
and to return from the function the pointer out. In this case you could write for example
puts( str_reverse( output, input ) );
Take into acount that function fgets usually also stores the new line character in the string. You should remove it. you can do it the following way
input[strcspn( input, "\n" )] = '\0';
Also instead of the type int in this statement
int i = strlen(in);
it is better to use type size_t.
size_t i = strlen(in);
It is the type of the return value of the function strlen. But in this case you should also to write the loop correctly.:)

Resources