Assignment makes integer from pointer without a cast как исправить

Coming from a Java background I'm learning C, but I find those vague compiler error messages increasingly frustrating. Here's my code: /* * PURPOSE * Do case-insensetive string comparison. ...

As others already noted, in one case you are attempting to return cString (which is a char * value in this context — a pointer) from a function that is declared to return a char (which is an integer). In another case you do the reverse: you are assigning a char return value to a char * pointer. This is what triggers the warnings. You certainly need to declare your return values as char *, not as char.

Note BTW that these assignments are in fact constraint violations from the language point of view (i.e. they are «errors»), since it is illegal to mix pointers and integers in C like that (aside from integral constant zero). Your compiler is simply too forgiving in this regard and reports these violations as mere «warnings».

What I also wanted to note is that in several answers you might notice the relatively strange suggestion to return void from your functions, since you are modifying the string in-place. While it will certainly work (since you indeed are modifying the string in-place), there’s nothing really wrong with returning the same value from the function. In fact, it is a rather standard practice in C language where applicable (take a look at the standard functions like strcpy and others), since it enables «chaining» of function calls if you choose to use it, and costs virtually nothing if you don’t use «chaining».

That said, the assignments in your implementation of compareString look complete superfluous to me (even though they won’t break anything). I’d either get rid of them

int compareString(char cString1[], char cString2[]) { 
    // To lowercase 
    strToLower(cString1); 
    strToLower(cString2); 

    // Do regular strcmp 
    return strcmp(cString1, cString2); 
} 

or use «chaining» and do

int compareString(char cString1[], char cString2[]) { 
    return strcmp(strToLower(cString1), strToLower(cString2)); 
} 

(this is when your char * return would come handy). Just keep in mind that such «chained» function calls are sometimes difficult to debug with a step-by-step debugger.

As an additional, unrealted note, I’d say that implementing a string comparison function in such a destructive fashion (it modifies the input strings) might not be the best idea. A non-destructive function would be of a much greater value in my opinion. Instead of performing as explicit conversion of the input strings to a lower case, it is usually a better idea to implement a custom char-by-char case-insensitive string comparison function and use it instead of calling the standard strcmp.

When I declare a char * to a fixed string and reuse the pointer to point to another string

/* initial declaration */
char *src = "abcdefghijklmnop";
.....

/* I get the   "warning: assignment makes integer from pointer without a cast" */
*src ="anotherstring";

I tried to recast the pointer but no success.

apose's user avatar

apose

3401 silver badge10 bronze badges

asked Feb 25, 2011 at 20:25

lcutler's user avatar

1

The expression *src refers to the first character in the string, not the whole string. To reassign src to point to a different string tgt, use src = tgt;.

answered Feb 25, 2011 at 20:27

Jeremiah Willcock's user avatar

When you write the statement

*src = "anotherstring";

the compiler sees the constant string "abcdefghijklmnop" like an array. Imagine you had written the following code instead:

char otherstring[14] = "anotherstring";
...
*src = otherstring;

Now, it’s a bit clearer what is going on. The left-hand side, *src, refers to a char (since src is of type pointer-to-char) whereas the right-hand side, otherstring, refers to a pointer.

This isn’t strictly forbidden because you may want to store the address that a pointer points to. However, an explicit cast is normally used in that case (which isn’t too common of a case). The compiler is throwing up a red flag because your code is likely not doing what you think it is.

It appears to me that you are trying to assign a string. Strings in C aren’t data types like they are in C++ and are instead implemented with char arrays. You can’t directly assign values to a string like you are trying to do. Instead, you need to use functions like strncpy and friends from <string.h> and use char arrays instead of char pointers. If you merely want the pointer to point to a different static string, then drop the *.

answered Feb 25, 2011 at 21:10

bta's user avatar

btabta

43.2k6 gold badges71 silver badges98 bronze badges

The warning comes from the fact that you’re dereferencing src in the assignment. The expression *src has type char, which is an integral type. The expression "anotherstring" has type char [14], which in this particular context is implicitly converted to type char *, and its value is the address of the first character in the array. So, you wind up trying to assign a pointer value to an integral type, hence the warning. Drop the * from *src, and it should work as expected:

src = "anotherstring";

since the type of src is char *.

answered Feb 25, 2011 at 21:42

John Bode's user avatar

John BodeJohn Bode

117k18 gold badges116 silver badges194 bronze badges

What Jeremiah said, plus the compiler issues the warning because the production:

*src ="anotherstring";

says: take the address of «anotherstring» — «anotherstring» IS a char pointer — and store that pointer indirect through src (*src = … ) into the first char of the string «abcdef…» The warning might be baffling because there is nowhere in your code any mention of any integer: the warning seems nonsensical. But, out of sight behind the curtain, is the rule that «int» and «char» are synonymous in terms of storage: both occupy the same number of bits. The compiler doesn’t differentiate when it issues the warning that you are storing into an integer. Which, BTW, is perfectly OK and legal but probably not exactly what you want in this code.

— pete

answered Feb 25, 2011 at 20:52

Pete Wilson's user avatar

Pete WilsonPete Wilson

8,5316 gold badges38 silver badges50 bronze badges

1

structure of node:-

struct node {
  char key[10];
  struct node *left, *right;
};

Also it may arrive when you are doing something like this

struct node *newNode(char item[10]) {
  struct node *temp = (struct node *)malloc(sizeof(struct node));
  temp->key[10] = item;
  temp->left = temp->right = NULL;
  return temp;
}

It will show warning in line 3 and all of your code will be messed up. Good news is:-

you have to prove that it is an array and it can be simply done by

temp->key[10] = item[10];

As simple as that…

answered Mar 9, 2022 at 2:28

Aryaman Godara's user avatar

Как правило встречаются такие способы передачи данных из функции.

Во-первых, можно в функции создать статический массив в функции, а потом возращать указатель на него. Как то так:

Код: Выделить всё

#define MAXLINE 100
char* get_name_addition(void)
{
    static char name[MAXLINE];
    fgets(name,MAXLINE,stdin);
    ... // Какие-то дополнительные действия
    return *name;
}

Типичная практика для Unix-а (насколько могу судить), но, как нетрудно заметить, это функция не совместима с многопоточным программированием. Эту функцию можно переделать для многопоточных приложений, используя собственные данные потоков (Thread-Specific Data), но лучше сразу делать иначе.

Пожалуй самая распространенная практика — это передать в функцию буфер для записи — этот буфер не будет привязан к стеку выполняемой функции.

Код: Выделить всё

#define MAXLINE 100
int get_name_addition(char *name, size_t n)
{
    fgets(name, n, stdin);
    ...
    return 0;
}

Не всегда можно заранее угадать, сколько нужно выделить места для буфера — это подчас известно только в вызываемой функции. К примеру в Win эта задача часто решается повторным вызовом одной функции: первый раз задаем нулевой буфер и узнаем необходимый размер; второй раз вызывает функцию с буфером достаточного размера и получаем в него данные. Здесь, в никсах, мне такого не попадалось.

Но встречается более простой способ. В вызываемой функции malloc-ом создаем буфер. Но для его очистки создаем еще одну дополнительную функцию.

Код: Выделить всё

#define MAXLINE 100
char* get_name_addition(void)
{
    char* name;
    name = (char*)malloc(MAXLINE);
    fgets(name, MAXLINE, stdin);
    ...
    return name;
}

void get_name_free(char* name)
{
    free(name);
}

Соответственно, использовать это надо так:

Код: Выделить всё

int main(void)
{
    char *name;
    name = get_name_addition();
    // Что-то делаем
    ...

    get_name_free(name);

    return 0;
}

Конечно, в данном случае можно было бы в main-е просто вызвать free. Но, во первых, возращаемые данные не обязательно будут линейным куском памяти, а могут оказаться каким нибудь связным списком. Во-вторых, если функция та находится в разделяемой библиотеке, я бы не стал исключать случай, что там могла быть слинкована другая реализация malloc-а.

  • Home
  • Forum
  • The Ubuntu Forum Community
  • Ubuntu Specialised Support
  • Development & Programming
  • Programming Talk
  • [SOLVED] C — assigment makes integer from pointer without a cast warning

  1. [SOLVED] C — assigment makes integer from pointer without a cast warning

    I know it’s a common error, and I’ve tried googling it, looked at a bunch of answers, but I still don’t really get what to do in this situation….
    Here’s the relevant code:

    Code:

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    int main( int argc, char *argv[] )
    {
        char path[51];
        const char* home = getenv( "HOME" );
    
        strcpy( path, argv[1] );
    
        path[1] = home;
    
        return 0;
    }

    — there is more code in the blank lines, but the issue’s not there (I’m fairly sure), so didn’t see the point in writing out 100 odd lines of code.
    I’ve tried some stuff like trying to make a pointer to path[1], and make that = home, but haven’t managed to make that work (although maybe that’s just me doing it wrong as opposed to wrong idea?)

    Thanks in advance for any help


  2. Re: C — assigment makes integer from pointer without a cast warning

    path[1] is the second element of a char array, so it’s a char. home is a char *, i.e. a pointer to a char.

    You get the warning because you try to assign a char* to a char.

    Note also the potential to overflow your buffer if the content of the argv[1] argument is very long. It’s usually better to use strncpy.

    Last edited by r-senior; March 10th, 2013 at 03:03 PM.

    Reason: argv[1] would overflow, not HOME. Corrected to avoid confusion.

    Please create new threads for new questions.
    Please wrap code in code tags using the ‘#’ button or enter it in your post like this: [code]…[/code].


  3. Re: C — assigment makes integer from pointer without a cast warning

    You can try something like this:

    Code:

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    int main( int argc, char *argv[] )
    {
      char *path;
      const char *home = getenv("HOME");
    
      path = malloc(strlen(home) + 1);
      if (!path) {
        printf("Errorn");
        return 0;
      }
      strcpy(path, home);
      printf("path = %sn", path);
    
      // if you want to have argv[1] concatenated with path
      if (argc >= 2) {
        path = malloc(strlen(home) + strlen(argv[1]) + 1);
        strcpy(path, argv[1]);
        strcat(path, home);
        printf("%sn", path);
      }
    
      // if you want an array of strings, each containing path, argv[1]...
      char **array;
      int i;
    
      array = malloc(argc * sizeof(char*));
    
      array[0] = malloc(strlen(home) + 1);
      strcpy(array[0], home);
      printf("array[0] = %sn", array[0]);
    
      for (i = 1; i < argc; i++) {
        array[i] = malloc(strlen(argv[i]) + 1);
        strcpy(array[i], argv[i]);
        printf("array[%d] = %sn", i, array[i]);
      }
      // now array[i] will hold path and all the argv strings
    
      return 0;
    }

    Just as above, your path[51] is a string while path[1] is only a character, so you can’t use strcpy for that.

    Last edited by Christmas; March 10th, 2013 at 09:51 PM.


  4. Re: C — assigment makes integer from pointer without a cast warning

    Quote Originally Posted by Christmas
    View Post

    You can try something like this:

    Code:

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    int main( int argc, char *argv[] )
    {
      char *path;
      const char *home = getenv("HOME");
    
      path = malloc(strlen(home) + 1);
      if (!path) {
        printf("Errorn");
        return 0;
      }
      strcpy(path, home);
      printf("path = %sn", path);
    
      // if you want to have argv[1] concatenated with path
      if (argc >= 2) {
        path = malloc(strlen(home) + strlen(argv[1]) + 1);
        strcpy(path, argv[1]);
        strcat(path, home);
        printf("%sn", path);
      }
    
      // if you want an array of strings, each containing path, argv[1]...
      char **array;
      int i;
    
      array = malloc(argc * sizeof(char*));
    
      array[0] = malloc(strlen(home) + 1);
      strcpy(array[0], home);
      printf("array[0] = %sn", array[0]);
    
      for (i = 1; i < argc; i++) {
        array[i] = malloc(strlen(argv[i]) + 1);
        strcpy(array[i], argv[i]);
        printf("array[%d] = %sn", i, array[i]);
      }
      // now array[i] will hold path and all the argv strings
    
      return 0;
    }

    Just as above, your path[51] is a string while path[1] is only a character, so you can’t use strcpy for that.

    Excellent point. I’ve basically fixed my problem by reading up on pointers again (haven’t done any C for a little while, so forgot some stuff), and doing:
    the code doesn’t moan at me when I compile it, and it runs okay (for paths which aren’t close to 51 at least), but after reading what you read, I just wrote a quick program and found out that getenv(«HOME») is 10 characters long, not 1 like I seem to have assumed, so I’ll modify my code to fix that.


  5. Re: C — assigment makes integer from pointer without a cast warning

    Yes, getenv will return the path to your home dir, for example /home/user, but path[1] = *home will still assign the first character of home to path[1] (which would be ‘/’).


Tags for this Thread

Bookmarks

Bookmarks


Posting Permissions

Понравилась статья? Поделить с друзьями:
  • Assetto corsa error steam
  • Assetto corsa error report
  • Assetto corsa csp unexpected error
  • Assetto corsa competizione ошибка fatal error
  • Assets standard assets utility simpleactivatormenu cs 3 21 error cs1002 expected