Char invalid conversion from 'char*' to 'char' [-fpermissive] [closed] - c

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 5 years ago.
Improve this question
I have problems with invalid conversion from 'char*' to 'char' [-fpermissive].
In here, I am shifting data one digit.
char text[]="5052.4318" ,temp;
When I write like this, ok, it is working but I need to read data from array[3].
How can I handle this problem?
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main ()
{
char *array[3];
array[3]="5052.4318";
char text[]={array[3]} ,temp;
int text_len = strlen (text),i;
for (i =0; i <=text_len - 1; i++)
{
if (text[i] == '.')
{
temp = text[i-1];
text[i-1] = text[i];
text[i] = temp;
}
}
printf ("%s\n", text);
return 0;
}
Working
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main (void) {
char *array[1] = {"5052.4318"};
size_t text_len = strlen(array[0]);
char text[text_len + 1], temp;
int i;
strcpy(text, array[0]);
for (i=0; i <=text_len - 1; i++){
if (text[i] == '.') {
temp = text[i-1];
text[i-1] = text[i];
text[i] = temp;
}
}
printf ("%s\n", text);
}
In here I am trying read GPS data and this data is GPRMC so firstly i need to parse these data after have to convert to google maps format(latitude need longitude).
$GPRMC,093612.000,A,5052.43525,N,00440.11204,E,0.0,0.0,130917,,,A*6C
5052.43525 is latitude value. Firstly I need to shift data like this 50.5243525.Again shift>>After divide number of 60=> 52.43525/60=0.87392083.
So result should be 50.87392083. Another problem I shouldnt use atof command for string to float value. Because I am using Coocox and is not working in Debug.Maybe I need to use null terminal. I am sharing this code which progressing I am doing.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main ()
{
//char buf[]
="$GPRMC,121212,A,4807.038,N,01131.000,E,022.4,084.4,030611,003.1,W*6A";
char T[100];
sprintf(T,
"%s","$GPRMC,093612.000,A,5052.43525,N,00440.11204,E,0.0,0.0,130917,,,A*6C");
printf(T);
char *buf[]={T};
int i = 0;
char *p = strtok (*buf, ",");
char *array[12];
while (p !=0)
{
array[i++] = p;
p = strtok (0, ",");
}
for (i = 0; i < 11; ++i) {
array[i];
printf("%s\n",array[i]);
}
//char *array[3] = {"5052.4318"};
size_t text_len = strlen(array[3]);
char text[text_len +1], temp;
int i1;
strcpy(text, array[3]);
for (i1 =0; i1 <=text_len - 1; i1++)
{
if (text[i1] == '.')
{
temp = text[i1-1];
text[i1-1] = text[i1];
text[i1] = temp;
}
}
for (i1 =0; i1 <=text_len - 1; i1++)
{
if (text[i1] == '.')
{
temp = text[i1-1];
text[i1-1] = text[i1];
text[i1] = temp;
}
}
char *buf1[]={text};
int i3 = 0;
char *p1 = strtok (*buf1, ".");
char *array1[2];
while (p1 !=0)
{
array1[i3++] = p1;
p1 = strtok (0, ".");
}
for (i3 = 0; i3 < 2; ++i3) {
array1[i3];
} double d;
float m;
int k=0;
d= (atof(array1[1])/6000);
char s[1]= {d};
m=(atof(array1[0]));
printf("%f\n",m);
printf("%lf\n",d);
return 0;
}
Result should be 50.87392083.
I havent completed.
Thanks

I'm not completely sure what you are trying to achieve but there are some problems with the first part of your code. Your initialization lines are not really correct.
I think that you are trying to "divide by 10" your string. Keeping your algorithm, I've fixed some of the issues to have it compiled.
// #include <iostream> // This is C not C++. Also you include stdio.h...
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main ()
{
char array[] = "5052.4318"; // This initialization
// one of your errors
char * text = array + 3; // I don't know why you are pointing
// fourth element of the array, but you may do
// in this way
// Let's say I prefer to start from the starting of
// the array
text = array;
printf ("%s\n", text);
int text_len = strlen(text);
for (int i = 1; i <= text_len - 1; i++) { // You will have some problem
// if you start from 0...
if (text[i] == '.') {
char temp; // temp is used only here, so let's define it in the
// only scope that needs it.
temp = text[i - 1]; // This -1 is the reason why you may start
// the for from 1, instead of 0.
text[i - 1] = text[i];
text[i] = temp;
}
}
printf ("%s\n", text);
return 0;
}
It prints out:
5052.4318
505.24318
Is that what you want to achieve?
The for starts from 1 to handle strings like ".1234".
Also: -fpermissive is a flag that controls the "dialect" of the C++ compiler. It is not something that you see when you are compiling in C. Since you included iostream, your compiler switched automatically to a C++ compiler. You must be really careful in this things.

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main ()
{
char text[30]="5052.4318",temp;
int text_len = strlen (text),i;
//printf("%s\n%d\n",text,text_len);
for (i =0; i <=text_len - 1; i++)
{
if (text[i] == '.')
{
temp = text[i-1];
text[i-1] = text[i];
text[i] = temp;
}
}
printf ("%s\n", text);
return 0;
}
You don't need to use an extra character array to achieve your desired result.

Related

Why am I getting a message segmentation fault?

Using C, I am trying to implement a function that converts word into mutated_word according to the key string_word. eg: when word is "HE", with the key "QWERTYUIOPASDFGHJKLZXCVBNM", the mutated_word should become "IT". But it keeps giving segmentation fault, not sure how to improve.
#include <cs50.h>
#include <stdio.h>
#include <string.h>
int main(void) {
string word = "HE" ;
string string_word = "QWERTYUIOPASDFGHJKLZXCVBNM";
char mutated_word[strlen(word)];
for (int i = 0; word[i] != '\0'; i++) {
string_word[(int)word[i] - 65] = mutated_word[i];
}
printf("%s", mutated_word);
}
You need to terminate the new string with null character.
Your array is too small
Use the correct type for indexes (int is not the correct one)
Check if the character is the letter. If not decide what to do (in my example I convert all letters to uppercase, other chars are left as they are)
Do not use magic numbers. Instead of 65 use 'A'
Your assignment is wrong, you actually want something right opposite.
It will not work with all character encoding.
#include <ctype.h>
#include <stdio.h>
int main (void)
{
string word = "HE" ;
string string_word = "QWERTYUIOPASDFGHJKLZXCVBNM" ;
char mutated_word [strlen(word) + 1];
size_t i;
for (i = 0; word[i] != '\0'; i++)
{
if(isalpha((unsigned char)word[i]))
{
mutated_word[i] = string_word[toupper((unsigned char)word[i]) - 'A'];
}
else
{
mutated_word[i] = word[i];
}
}
mutated_word[i] = 0;
printf("%s", mutated_word);
}
https://godbolt.org/z/4zqq98Y3n
To make it more portable:
#include <ctype.h>
#include <stdio.h>
#include <string.h>
#include <stddef.h>
ptrdiff_t findIndex(const char ch, const char * restrict dict)
{
char *result = strchr(dict, ch);
if(!result) return -1;
return result - dict;
}
int main (void)
{
string word = "He124" ;
string string_word = "QWERTYUIOPASDFGHJKLZXCVBNM" ;
string dict = "ABCDEFGHIJKLMNOPQRSTUVXYWZ";
ptrdiff_t index;
char mutated_word [strlen(word) + 1];
size_t i;
for (i = 0; word[i] != '\0'; i++)
{
if(isalpha((unsigned char)word[i]))
{
index = findIndex(toupper((unsigned char)word[i]), dict);
}
else index = -1;
mutated_word[i] = index == -1 ? word[i] : string_word[index];
}
mutated_word[i] = 0;
printf("%s", mutated_word);
}
https://godbolt.org/z/KW8TxxEvq
You program crashes because the assignment is in the wrong order: string_word[(int)word[i] - 65] = mutated_word[i]; is attempting to modify a string literal, which has undefined behavior. Note also that the destination string must be 1 byte longer for the null terminator, which you must set explicitly.
Here is a more portable version:
#include <ctype.h>
#include <stdio.h>
#include <string.h>
int main(void) {
const char *word = "HE";
const char *normal_word = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
const char *string_word = "QWERTYUIOPASDFGHJKLZXCVBNM";
char mutated_word[strlen(word) + 1];
unsigned char c;
const char *p;
size_t i;
for (i = 0; (c = word[i]) != '\0'; i++) {
if (isupper(c) && (p = strchr(normal_word, c)) != NULL) {
c = string_word[p - normal_word];
} else
if (islower(c) && (p = strchr(normal_word, toupper(c))) != NULL) {
c = string_word[p - normal_word];
c = tolower(c);
}
mutated_word[i] = c;
}
mutated_word[i] = '\0';
printf("%s\n", mutated_word);
return 0;
}

Program prints unrelated chars

I wanted to split an array to 2 arrays that the first one contains the lowercased letters of the original array and the second one contains the uppercased letters and from some reason it prints some unrelated chars.
#include <stdio.h>
#include <string.h>
#define LEN 8
int main(void)
{
char str[] = "SHaddOW";
char smallStr[LEN], bigStr[LEN];
int i = 0;
int indexSmall = 0;
int indexBig = 0;
for (i = 0; i <= LEN; i++)
{
if (str[i] <= 'Z')
{
smallStr[indexSmall] = str[i];
indexSmall++;
}
if (str[i] >= 'Z')
{
bigStr[indexBig] = str[i];
indexBig++;
}
}
printf("1: ");
puts(smallStr);
printf("2: ");
puts(bigStr);
system("PAUSE");
return 0;
}
Don't define length before you create the string to test.
Create it's length after defining the string to test.
Copy the characters as you encounter them, but as #Ed Heal says you must add a null terminator so that you can print out the two strings (they aren't really strings until they are null terminated).
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
int main (void)
{
char str[] = "SHaddOW";
int len = strlen(str) +1;
char smallStr[len], bigStr[len];
char term[] = {'\0'};
int n, s, b;
s=0;
b=0;
for(n=0; n<len; n++) {
if(islower(str[n])) {
memcpy(smallStr +s, str +n, 1);
s++;
} else if (isupper(str[n])){
memcpy(bigStr +b, str +n, 1);
b++;
}
}
memcpy(smallStr + s, term, 1);
memcpy(bigStr + b , term, 1 );
printf("Upper: %s\n", bigStr);
printf("Lower: %s\n", smallStr);
}
Output:
Upper: SHOW
Lower: add
Add this to the if structure (and other code to support it)
} else {
memcpy(anyStr +a, str +n, 1);
a++;
}
then:
char str[] = ".S1H2a3d4d5O6W.";
and:
printf("Anything else: %s\n", anyStr);
returns:
Upper: SHOW
Lower: add
Anything else: .123456.
A more compact approach with (perhaps) more meaningful variable names:
#include <stdio.h>
#include <ctype.h>
#include <stdint.h>
#include <string.h>
int main ( void ) {
const char str[] = "SHaddOW";
size_t len = strlen(str); /* better to get actual length */
char lowers[len + 1]; /* add one for the nul char */
char uppers[len + 1]; /* (see below) */
int c;
int i = 0;
int n_upper = 0;
int n_lower = 0;
while ((c = str[i++]) != '\0') {
if (isupper(c)) uppers[n_upper++] = c; /* no need to reinvent */
if (islower(c)) lowers[n_lower++] = c; /* the wheel here */
}
uppers[n_upper] = '\0'; /* the nul char ('\0') marks */
lowers[n_lower] = '\0'; /* the end of a C "string" */
printf("1: %s\n", lowers);
printf("2: %s\n", uppers);
return 0;
}
Notes
If you are super concerned about efficiency you could add an else before if (islower...
Adding const means you "promise" the characters in the array won't be changed.
The type size_t is an integer type, but may be larger than int. It is the correct type for the return of strlen(). It is defined in <stdint.h>. None the less, using int will almost always work (on most systems a string would have to be 'yooooge' for its length to be bigger than an int can hold).
The variable c is declared as int instead of char because int is the proper type for the isXXXXX() functions (which are defined in <ctype.h>). It is also a good habit to get into because of the parallels between this loop and another common idiom while ((c = fgetc(fp)) != EOF) ....
You should consider using isupper() and islower() functions. Code would be cleaner. And what if you have some non alpha characters? Your conditions won't work.
for (i = 0; i < LEN; i++)
{
if (islower(str[i]))
{
smallStr[indexSmall] = str[i];
indexSmall++;
}
else if (isupper(str[i]))
{
bigStr[indexBig] = str[i];
indexBig++;
}
}
As #Ed Heal mention. To avoid printing rubbish, after for loopt you should add a null characters to arrays.
smallStr[indexSmall] = '\0';
bigStr[indexBig] = '\0';

Hex/Dec Program in C getting the wrong output and cant use Scanf

Whenever I run my program, I think that I am getting the wrong output using the included test strings, though I think my first function is working. Tthe files I have are xbits.c xbits.h and two versions of showxbits.c, one that is instructor provided and the other is the one I am trying to use scanf with. The program is supposed to convert an integer to a hex string and then a hex string to an integer. My main problem is, while I think that my code works with the instructor test input, I know it doesn't work with the scanf showxbits because it gives answers such as 0xS when 127 is inputed.
Here is the xbits.c
#include <stdio.h>
#include <math.h>
int hex_To_dec(int c) {
char hex_values[] = "aAbBcCdDeEfF";
int i;
int answer = 0;
for (i=0; answer == 0 && hex_values[i] != '\0'; i++) {
if (hex_values[i] == c) {
answer = 10 + (i/2);
}
}
return answer;
}
/* function represents the int n as a hexstring which it places in the
hexstring array */
void itox(char* s, int n)
{
char *digits = "0123456789ABCDEF";
int i=0,j;
char temp;
while(n > 0)
{
s[i] = digits[n % 16];
n /= 16;
i++;
}
s[i] = '\0'; // Add null terminator
i--;
// Now reverse it in place
for(j=0; j < i / 2; j++)
{
temp = s[j];
s[j] = s[i - j];
s[i - j] = temp;
}
}
/* function converts hexstring array to equivalent integer value */
int xtoi(char hexstring[]) {
//printf("in xtoi, processing %s\n", hexstring);
int answer = 0;
int i = 0;
int valid = 1;
int hexit;
if (hexstring[i] == '0') {
++i;
if (hexstring[i] == 'x' || hexstring[i] == 'X') {
++i;
}
}
while(valid && hexstring[i] != '\0') {
answer = answer * 16;
if(hexstring[i] >='0' && hexstring[i] <= '9') {
answer = answer + (hexstring[i] - '0');
}
else {
hexit = hex_To_dec(hexstring[i]);
if (hexit == 0) {
valid = 0;
}
else {
answer = answer + hexit;
}
}
++i;
}
if(!valid) {
answer = 0;
}
return answer;
}
Here is the showxbits.c provided by the instructor:
/*
* stub driver for functions to study integer-hex conversions
*
*/
#include <stdio.h>
#include <string.h>
#include "xbits.h"
#define ENOUGH_SPACE 1000 /* not really enough space */
int main() {
char hexstring[ENOUGH_SPACE];
int m=0, n = 0x79FEB220;
itox(hexstring, n);
/* for stub testing: create a fake input string */
strcpy(hexstring, "6BCD7890");
m = xtoi(hexstring);
printf("\t%12d %s %12d\n", n, hexstring, m);
return 0; /* everything is just fine */
}
And here is the showxbits that has scanf in it:
/*
* stub driver for functions to study integer-hex conversions
*
*/
#include <stdio.h>
#include <string.h>
#include "xbits.h"
#define ENOUGH_SPACE 100 /* not really enough space */
int main() {
char hexstring[ENOUGH_SPACE];
//int m=0, n = 0x79FEB220;
int n, m;
while ((scanf("%d", &n)) == 1) {
itox(hexstring, n);
m = xtoi( hexstring);
printf("%12d %s %12d\n", n, hexstring, m);
}
return 0; /* everything is just fine */
}
Like I said, I am getting weird outputs when using the scanf function. I am a complete beginner programmer and would really appreciate any help that can be offered. Thanks!
Because there is a mistake in the function itox , which would cause the wrong result when reverse string. Then, the wrong hexstring from itox will result in the abnormal output finally.
The quick fix is to replace j < i / 2 with j < i / 2 + 1
void itox(char* s, int n)
{
//......
// Now reverse it in place
for(j=0; j < i / 2 + 1 ; j++)
{
temp = s[j];
s[j] = s[i - j];
s[i - j] = temp;
}
}
You don't need to reverse the string to convert to hex ascii:
#include <stdio.h>
const char* hexlat="0123456789ABCDEF";
char *binaryToHex(unsigned int answer, char *result){
if(answer==0) return result;
else{
result=binaryToHex(answer>>4,result);
*result=hexlat[answer & 0x0F];
return result+1;
}
};
int main(void) {
unsigned int answer=0x12340ADF;
char hexAnswer[32];
*binaryToHex(answer,hexAnswer)='\0';
printf("%s",hexAnswer);
return 0;
}

How to transform a block of strings to an array of strings

I've got a block of strings, say "aaa\0bbbb\0ccccccc\0"
and I want to turn them into an array of strings.
I've tried to do so using the following code:
void parsePath(char* pathString){
char *pathS = malloc(strlen(pathString));
strcpy(pathS, pathString);
printf(1,"33333\n");
pathCount = 0;
int i,charIndex;
printf(1,"44444\n");
for(i=0; i<strlen(pathString) ; i++){
if(pathS[i]=='\0')
{
char* ith = malloc(charIndex);
strcpy(ith,pathS+i-charIndex);
printf(1,"parsed string %s\n",ith);
exportPathList[pathCount] = ith;
pathCount++;
charIndex=0;
}
else{
charIndex++;
}
}
return;
}
exportPathList is a global variable defined earlier in the code by
char* exportPathList[32];
when using that function exportPathList[i] contains garbage.
What am I doing wrong?
The answer to this SO question:
Parse string into argv/argc
deals with a similar issue, you might have a look.
You need to know how many strings are there or agree for an "end of strings". The simplest would be to have an empty string at the end:
aaa\0bbbb\0ccccccc\0\0
^^
P.S. is this homework?
First of all, since your strings are delimited by a null char, '\0', strlen will only report the size of the string up to the first '\0'. strcpy will copy until the first null character as well.
Further, you cannot know where the input string ends with this information. You either need to pass in the whole size or, for example, end the input with double null characters:
#include <stdio.h>
#include <string.h>
void parsePath(const char* pathString){
char buf[256]; // some limit
while (1) {
strcpy(buf, pathString);
pathString+=strlen(buf) + 1;
if (strlen(buf) == 0)
break;
printf("%s\n", buf);
}
}
int main()
{
const char *str = "aaa\0bbbb\0ccccccc\0\0";
parsePath(str);
return 0;
}
And you need some realloc's to actually create the array.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXSIZE 16
char* exportPathList[MAXSIZE] = {0};
size_t pathCount = 0;
void parsePath(char* pathString){
char *ptop, *pend;
ptop=pend=pathString;
while(*ptop){
while(*pend)++pend;
exportPathList[pathCount++]=strdup(ptop);
pend=ptop=pend+1;
}
}
int main(){
char textBlock[]= "aaa\0bbbb\0ccccccc\0";
//size_t size = sizeof(textBlock)/sizeof(char);
int i;
parsePath(textBlock);
for(i=0;i<pathCount;++i)
printf("%s\n", exportPathList[i]);
return 0;
}
The solution I've implemented was indeed adding double '\0' at the end of the string and using that in order to calculate the number of strings.
My new implementation (paths is the number of strings):
void parsePath(char* pathString,int paths){
int i=0;
while (i<paths) {
exportPathList[i] = malloc(strlen(pathString)+1);
strcpy(exportPathList[i], pathString);
pathString+=strlen(pathString);
i++;
}
}
I'd like to thank everyone that contributed.
My Implementation looks like this -> it follows the idea of argv and argc in a main funtion:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void){
char **args = (char**)malloc(100*sizeof(char));
char buff[100], input_string[100], letter;
for(int i = 0; i < 100; i++){
buff[i] = '\0';
input_string[i] = '\0';
}
for(int i = 0; (letter = getchar())!='\n'; i++){
input_string[i] = letter;
}
int args_num = 0;
for(int i = 0, j = 0; i < 100;i++){
if((input_string[i] == ' ')||(input_string[i]=='\0')){
//reset j = 0
j = 0;
args[args_num] = malloc(strlen(buff+1));
strcpy(args[args_num++],buff);
for(int i = 0; i < 100; i++)buff[i] = '\0';
}else buff[j++] = input_string[i];
}
for(int i = 0; i < args_num; i++){
printf("%s ",args[i]);
}
}
-> Every single word in your string can then be accessed with args[i]

Printing Array of Strings

I'm parsing a text file:
Hello, this is a text file.
and creating by turning the file into a char[]. Now I want to take the array, iterate through it, and create an array of arrays that splits the file into words:
string[0] = Hello
string[1] = this
string[2] = is
This is my code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "TextReader.h"
#include <ctype.h>
void printWord(char *string) {
int i;
for (i = 0; i < strlen(string); i ++)
printf("%c", string[i]);
printf("\n");
}
void getWord(char *string) {
char sentences[5][4];
int i;
int letter_counter = 0;
int word_counter = 0;
for (i = 0; i < strlen(string); i ++) {
// Checks if the character is a letter
if (isalpha(string[i])) {
sentences[word_counter][letter_counter] = string[i];
letter_counter++;
} else {
sentences[word_counter][letter_counter + 1] = '\0';
word_counter++;
letter_counter = 0;
}
}
// This is the code to see what it returns:
i = 0;
for (i; i < 5; i ++) {
int a = 0;
for (a; a < 4; a++) {
printf("%c", sentences[i][a]);
}
printf("\n");
}
}
int main() {
// This just returns the character array. No errors or problems here.
char *string = readFile("test.txt");
getWord(string);
return 0;
}
This is what it returns:
Hell
o
this
is
a) w
I suspect this has something to do with pointers and stuff. I come from a strong Java background so I'm still getting used to C.
With sentences[5][4] you're limiting the number of sentences to 5 and the length of each word to 4. You'll need to make it bigger in order to process more and longer words. Try sentences[10][10]. You're also not checking if your input words aren't longer than what sentences can handle. With bigger inputs this can lead to heap-overflows & acces violations, remember that C does not check your pointers for you!
Of course, if you're going to use this method for bigger files with bigger words you'll need to make it bigger or allocate it dymanically.
sample that do not use strtok:
void getWord(char *string){
char buff[32];
int letter_counter = 0;
int word_counter = 0;
int i=0;
char ch;
while(!isalpha(string[i]))++i;//skip
while(ch=string[i]){
if(isalpha(ch)){
buff[letter_counter++] = ch;
++i;
} else {
buff[letter_counter] = '\0';
printf("string[%d] = %s\n", word_counter++, buff);//copy to dynamic allocate array
letter_counter = 0;
while(string[++i] && !isalpha(string[i]));//skip
}
}
}
use strtok version:
void getWord(const char *string){
char buff[1024];//Unnecessary if possible change
char *p;
int word_counter = 0;
strcpy(buff, string);
for(p=buff;NULL!=(p=strtok(p, " ,."));p=NULL){//delimiter != (not isaplha(ch))
printf("string[%d] = %s\n", word_counter++, p);//copy to dynamic allocate array
}
}

Resources