illegal hardware instruction error when concatenating two strings in c - c

I want to loop through a text file and concatenate all the strings until a blank line is hit and then do the same for the next strings and so on. The result of each string concatenation should be added to an char* array:
char* element_arr[287];
void splitPassports(FILE* file_to_read){
char element[500];
char str[80];
int i = 0;
int j = 0;
while(j < FILELENGTH){
if (fgets(str,80, file_to_read) && !isBlank(str)){
strcat(element,str);
printf("The string is: %s\n",str);
}else if (isBlank(str)){
element_arr[i] = element;
memset(element, '\0', sizeof element);
printf("%s\n",element_arr[0]);
i++;
}
j++;
}
fclose(file_to_read);
}
However when I try to do this I get an illegal hardware instruction error (I'm on a Mac). How can I properly add the new strings to the existing one and then append that to my array and after that set it back to zero to do the same for the few lines until a blank line is hit?
I'm relatively new to C so thanks in advance :)

char element[] = ""; you declare the array which is 1 char long, so the strcat will always fail (unless the second string is also empty).
Even if you define it the correct way, the assignment element_arr[i] = element; you will assign the array element with the same reference every time, so the array will be simple filled with references to the same object.
while(!feof(file_to_read)) - read Why is “while ( !feof (file) )” always wrong?
I would recommend starting with the C book as you do not understand the basics of the language.

Dumb response to question 3, you could see if the problem is due to over-layering. I am also a Mac user, and my code will sometimes have errors occur due to having too many layers of functions etc. I don't know if anyone has already found the answer to question 3, however I genuinely hope this helps/helped.

Related

Why I can't initialize a pointer variable and can't use gets? [duplicate]

This question already has answers here:
Why is the gets function so dangerous that it should not be used?
(13 answers)
Closed 3 years ago.
I have this code in my book, but I tried to understand it for a long time, but I couldn't. So, the code takes input from the user, and prints the outputs word per line along with the size of the word. It also prints the output based on the line. And it exclude any . , ! etc..
Example:
Input:
Hello, I am new here.
trying to learn.
Output:
Words typed on line number 1:
Hello(5)
I(1)
am(2)
new(3)
here(4)
Words typed on line number 2:
trying(6)
to(2)
learn(5)
Also, The code works on my friends computer, but not on mine. I keep getting an error message as you can see below. Can you please explain it to me? Also, why it doesn't work with me? and how can I fix it? I tried to use fgets, but it didn't work.
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
int main()
{
char str[10][81];
char* ptoken, * ptr;
int i = 0, maxstr = 0;
char* exclude = " .,!\t"; // I get an error message here (This entity cannot be initialized.)
printf("Enter the text you want on multiple lines\n");
printf("after you enter every thing pres ctrl+z and Enter \n\n");
while (gets(str[i])) // I get an error message here (The identifier gets cant be found).
{
str[i++];
maxstr++;
}
for (i = 0; i < maxstr; i++) {
printf("\n<< Words typed on line number %d> \n", i + 1);
ptr = str[i];
ptoken = strtok(ptr, exclude);
while (ptoken != NULL) {
printf("strlen(%s) = %d\n", ptoken, strlen(ptoken));
ptoken = strtok(NULL, exclude);
}
}
return 0;
}
char* exclude = " .,!\t"; // I get an error message here (This entity cannot be initialized.)
Attempting to modify a string literal gives undefined behavior. The const prevents you from doing that by accident (i.e., code that attempts to write via the pointer won't compile, unless you remove the const qualifier, such as with a cast).
char const *exclude =" .,!\t";
while (gets(str[i])) // I get an error message here (The identifier gets cant be found).
gets is deprecated because it's dangerous, it may cause buffer overflow.
Instead use fgets
while (fgets(str[i],sizeof(str),stdin))
Point to be noted
printf("strlen(%s) = %d\n", ptoken, strlen(ptoken));
Return type of strlen() in long int use %ld
printf("strlen(%s) = %ld\n", ptoken, strlen(ptoken));
I keep getting an error message as you can see below. Can you please explain it to me?
Not precisely. Details depend somewhat on your compiler.
However, with respect to
while (gets(str[i])) // I get an error message here (The identifier gets cant be found).
, the problem is surely with function gets(). This incurably flawed function should never be used, and in recognition of that, it was removed from the C language in the 2011 version of the standard. Most compilers still accept it, at least under some circumstances, but some do reject it. Whether macro _CRT_SECURE_NO_WARNINGS is defined might make a difference to your compiler in this regard.
On the other hand, there is nothing wrong with
char* exclude = " .,!\t"; // I get an error message here (This entity cannot be initialized.)
as far as standard C is concerned, but it is nevertheless dangerous, because you are assigning exclude to point to a value that must not be modified, but that variable's type does not express the unmodifiablilty. A conforming compiler ought to accept the code anyway, but some will reject it under some circumstances.
Also, why it doesn't work with me? and how can I fix it?
The code has some subtle flaws, not limited to those I already mentioned, and whether any given compiler accepts it depends on the compiler and the compilation command. However, the two issues I've talked about can be resolved by
using fgets() instead of gets(). The former allows you to specify the size of the destination buffer, so that it is not overrun:
while (fgets(str[i], 80, stdin) >= 0)
Do note that there remain some peculiarities there, however, such as what happens when the input equals or exceeds 80 characters.
declaring exclude as a pointer to const char:
const char *exclude = " .,!\t";
It seems you are compiling the program as a C++ program. If so then you need to write for example
const char *exclude = " .,!\t";
^^^^^
The function gets is not a standard C or C++ function. Instead ise the function fgets.
In this while loop
while (gets(str[i])) // I get an error message here (The identifier gets cant be found).
{
str[i++];
maxstr++;
}
these statements
str[i++];
maxstr++;
do not make sense.
Rewrite the loop like
for ( ; maxstr < 10 && fgets( str[maxstr], sizeof( str[maxstr] ), stdin ) != NULL; maxstr++ )
{
str[maxstr][ strcspn( str[maxstr], "\n" )] = '\0';
}
I think this line
str[maxstr][ strcspn( str[maxstr], "\n" )] = '\0';
requires an explanation. The function fgets can append the new line character '\n' to the entered string. To remove it (more precisely to substitute the character for the zero-terminating character '\0') there is used the string function strcspn that finds the position of the new line character. After that the substitution is done.
Substitute these two statements
ptr = str[i];
ptoken = strtok(ptr, exclude);
for
ptoken = strtok( str[i], exclude);
that is the variable ptr is redundant.
And do not use magic numbers like for example 10. Use instead named constants.

I am trying to create a program that takes a name and outputs the initials but keep running into an array error

I am trying to create a program that take the input from the user and prints the first character of each word but every time I try to Here is my code.
#include <stdio.h>
#include <cs50.h>
#include <string.h>
int main(void)
{
char leng[100];
int len;
scanf("%s", &leng[100]);
len = strlen(&leng[100]);
char name[len];
//checking if at end or not
while (name[len] != '\0')
{
if (name[len] == ' ')
printf("%c", name[len + 1]);
len++;
}
}
Every time I give a name it shows an error something like:
index 3 out of bounds for type 'char [len]'
These two lines are incorrect:
scanf("%s", &leng[100]);
len = strlen(&leng[100]);
If you translate these into English, their meanings as written are:
Scan a string to the memory at the address of 101st element of the
leng array.
Get the length of the string that starts at the address
of the 101st element of the leng array.
The array index is out of bounds because leng[100] is past the end of the array. Remember that a 100 element array goes from 0 to 99, not from 1 to 100!
You want to be scanning into the base address of the array, and passing the base address of the array into strlen(). I'll leave the syntax for you to figure out from your textbook.
And by the way, you also have a problem in your code because you're reading your data into an array named leng, but your loop is working with an array named len. There are at least two additional problems in your code, but I'll leave them for you to debug.
There are a few things to consider with your code. As #richardschwartz already mentioned, you are not referencing your char arrays correctly. you have:
scanf("%s", &leng[100]);
len = strlen(&leng[100]);
You may want the following instead:
scanf("%s", leng);
len = strlen(leng);
Also, keep in mind that scanf with the %s flag will stop reading input once white-space is detected. For example, if you input "hello world",
scanf("%s", leng);
will only catch the characters "hello". To get around this, you could loop scanf to read multiple words and return the first character of each word as you desire.
Lastly, scanf is not advised for beginners though. See paxdiablo's excellent reason regarding lack of overflow protection, here: https://stackoverflow.com/a/1248017/6870832

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";

Unexpected result in pointer arithmetic, in C

I'm new to C and I'm trying to solve one of the exercise problem of K&R book. The problem is to detect the whether a given string ends with the same content of other string.
For example, if string one is ratandcat and string two is cat. Then it is true that string two ends in string one. To solve this, I came up with half a solution and I got struck with pointers.
My idea is to find the position where string one ends and also the position the string two starts, so that I can proceed further. I have this code:
int strEnd(char *s,char *t){
int ans,slength =0 ,tlength = 0;
while(*s++)
slength++;
while(*t++)
tlength++;
s += slength - tlength;
printf("%c\n",*t);
printf("%c\n",*s);
return ans;
}
void main() {
char *message = "ratandcat";
char *message2 = "at";
int a = strEnd(message,message2);
}
But strangely this outputs :
%
(and a blank space)
But I want my s pointer to point to a. But it doesn't. Whats going wrong here?
Thanks in advance.
One problem is that you have incremented the s pointer to the end of the string, and then you add more stuff to it. You could do that loop with something like:
while(s[slength])
++slength;
Another problem is that you are assuming that the s string is longer than the other. What if it's not? And fix the ; problem noted by Simon.
You have an extra semicolon at the end of
while(*t++);
This means that tlength is never incremented, as only the semicolon (empty statement) is executed in the loop.

Splitting a string in C into separate parts

I've been trying to write a function in C that detects palindromes. The program currently looks like the following:
#include <stdio.h>
#include <string.h>
int main()
{
char palindrome[24]; int palength; int halflength;
gets(palindrome);
palength = strlen(palindrome);
halflength = palength / 2;
printf("That string is %u characters long.\r\n", palength);
printf("Half of that is %u.\r\n", halflength);
return 0;
}
Right now it detects the length of a string, and also shows what half of that is. This is just to make sure it is working how I think it should be. What the rest of the function should do (if possible) is take the integer from "halflength" and use that to take that amount of characters off of the beginning and end of the string and store those in separate strings. From there I'd be able to compare the characters in those, and be able return true or false if the string is indeed a palindrome.
TL;DR - Is it possible take a certain amount of characters (in this case the integer "halflength") off the front and end of a string and store them in separate variables. Read above for more information on what I'm trying to do.
P.S. - I know not to use gets(), but didn't feel like writing a function to truncate \n off of fgets().
int len = strlen(palindrome) - 1; // assuming no \n
int half = len << 1;
for (int i=0; i<=half; ++i)
if(palindrome[i] != palindrome[len-i])
return false;
return true;
What if you do something like this,
char *str1="lol",*str2;
str2=strrev(str1);
//if both are same then it actually is a palindrome ; )
Found out I was approaching the problem wrong. How I should be doing this is iterating over the characters using a pointer both backwards and forwards. Although if you'd still like to answer the original question it could still be useful at some point.

Resources