C++ сравните массив символов со строкой
Я пытаюсь сравнить массив символов со строкой, например:
const char *var1 = " ";
var1 = getenv("myEnvVar");
if(var1 == "dev")
{
// do stuff
}
Это утверждение if никогда не проверяется как true... когда я выводил var1, это "dev", я думал, может быть, это имеет какое-то отношение к нулевой завершенной строке, но strlen" dev " и var1 равны... Я также подумал, что, возможно, var1 = = " dev "сравнивал" dev " с местоположением памяти var1 вместо значения. * var1 = = " dev " приводит к ошибке.... попробовал многое, наверное, простой решение для разработчика saavy c++ (я не закодировал c++ за долгое время).
изменить: мы пытались
if(strcmp(var1, "dev") == 0)
и
if(strncmp(var1, "dev", 3) == 0)
спасибо
edit: после тестирования дома я просто предложу своему коллеге изменить тип данных на строку. Я считаю, что он сравнивал массив символов большого размера со строкой. Я собрал программу, которая выводит sizeof, strlen и т. д., Чтобы помочь нам работать с ней. Спасибо всем за помощь.
6 ответов
использовать strcmp()
чтобы сравнить содержимое строк:
if (strcmp(var1, "dev") == 0) {
}
объяснение: в C строка является указателем на место памяти, которое содержит байты. Сравнивая char*
до char*
использование оператора равенства не будет работать должным образом, потому что вы сравниваете ячейки памяти строк, а не их содержимое байта. Такая функция, как strcmp()
будет перебирать обе строки, проверяя их байты, чтобы увидеть, равны ли они. strcmp()
возвращает 0, если они равны, и ненулевое значение, если они отличаются. Дополнительные сведения см. В разделе manpage.
вы не работаете со строками. Ты работаешь с указателями.
var1
- это указатель char (const char*
). Это не струна. Если это null-terminated, то некоторые функции C будут лечения это как строка, но это принципиально просто указатель.
поэтому, когда вы сравниваете его с массивом char, массив распадается на указатель, а затем компилятор пытается найти operator == (const char*, const char*)
.
такой оператор существует. Он принимает два указателя и возвращает true
если они указывают на один и тот же адрес. Поэтому компилятор вызывает это, и ваш код ломается.
если вы хотите сделать сравнение строк, вы должны сказать компилятору, что вы хотите иметь дело с строки, а не указатели.
способ C сделать это-использовать strcmp
функция:
strcmp(var1, "dev");
это вернет ноль, если две строки равной. (Он вернет значение больше нуля, если левая сторона лексикографически больше, чем правая сторона, и значение меньше нуля в противном случае.)
Итак, чтобы сравнить для равенства, вам нужно сделать один из них:
if (!strcmp(var1, "dev")){...}
if (strcmp(var1, "dev") == 0) {...}
однако, C++ имеет очень полезный string
класса. Если мы используем это, ваш код становится немного проще. Конечно, мы могли бы создать строки из обоих аргументов, но нам нужно сделать это только с одним из них:
std::string var1 = getenv("myEnvVar");
if(var1 == "dev")
{
// do stuff
}
теперь компилятор встречает сравнение между строкой и char pointer. Он может справиться с этим, потому что указатель char может быть неявно преобразован в строку, давая сравнение string/string. И они ведут себя именно так, как вы и ожидали.
в этом коде вы не сравниваете строковые значения, вы сравниваете значения указателя. Если вы хотите сравнить строковые значения нужно использовать функцию сравнения строк, таких как strcmp.
if ( 0 == strcmp(var1, "dev")) {
..
}
" dev " не является string
Это const char *
как var1
. Таким образом, вы действительно сравниваете адреса памяти. Быть тем var1
является указателем char,*var1
- это один символ (первый символ последовательности символов, чтобы быть точным). Вы не можете сравнить char с указателем char, поэтому это не сработало.
поскольку это помечено как c++, было бы разумно использовать std::string
вместо указателей char, которые заставили бы == работать так, как ожидалось. (Вы просто нужно будет сделать const std::string var1
вместо const char *var1
.
более стабилизированная функция, также получает освобожданной складчатости строки.
// Add to C++ source
bool string_equal (const char* arg0, const char* arg1)
{
/*
* This function wraps string comparison with string pointers
* (and also works around 'string folding', as I said).
* Converts pointers to std::string
* for make use of string equality operator (==).
* Parameters use 'const' for prevent possible object corruption.
*/
std::string var0 = (std::string) arg0;
std::string var1 = (std::string) arg1;
if (var0 == var1)
{
return true;
}
else
{
return false;
}
}
и добавить объявление на заголовок
// Parameters use 'const' for prevent possible object corruption.
bool string_equal (const char* arg0, const char* arg1);
для использования просто поместите вызов 'string_equal' как условие if (или тройного) оператора / блока.
if (string_equal (var1, "dev"))
{
// It is equal, do what needed here.
}
else
{
// It is not equal, do what needed here (optional).
}
источник: sinatramultimedia / fl32 кодек (это написано мной)
ваши мысли об этой программе ниже
#include <stdio.h>
#include <string.h>
int main ()
{
char str[][5] = { "R2D2" , "C3PO" , "R2A6" };
int n;
puts ("Looking for R2 astromech droids...");
for (n=0 ; n<3 ; n++)
if (strncmp (str[n],"R2xx",2) == 0)
{
printf ("found %s\n",str[n]);
}
return 0;
}
//outputs:
//
//Looking for R2 astromech droids...
//found R2D2
//found R2A6
когда вы должны думать о вводе чего-то в массив, а затем использовать функции strcmp, такие как программа выше ... проверьте измененную программу ниже
#include <iostream>
#include<cctype>
#include <string.h>
#include <string>
using namespace std;
int main()
{
int Students=2;
int Projects=3, Avg2=0, Sum2=0, SumT2=0, AvgT2=0, i=0, j=0;
int Grades[Students][Projects];
for(int j=0; j<=Projects-1; j++){
for(int i=0; i<=Students; i++) {
cout <<"Please give grade of student "<< j <<"in project "<< i << ":";
cin >> Grades[j][i];
}
Sum2 = Sum2 + Grades[i][j];
Avg2 = Sum2/Students;
}
SumT2 = SumT2 + Avg2;
AvgT2 = SumT2/Projects;
cout << "avg is : " << AvgT2 << " and sum : " << SumT2 << ":";
return 0;
}
изменить на строку, за исключением того, что он читает только 1 вход и выбрасывает остальные может быть, нужно два для петель и два указателя
#include <cstring>
#include <iostream>
#include <string>
#include <stdio.h>
using namespace std;
int main()
{
char name[100];
//string userInput[26];
int i=0, n=0, m=0;
cout<<"your name? ";
cin>>name;
cout<<"Hello "<<name<< endl;
char *ptr=name;
for (i = 0; i < 20; i++)
{
cout<<i<<" "<<ptr[i]<<" "<<(int)ptr[i]<<endl;
}
int length = 0;
while(name[length] != '')
{
length++;
}
for(n=0; n<4; n++)
{
if (strncmp(ptr, "snit", 4) == 0)
{
cout << "you found the snitch " << ptr[i];
}
}
cout<<name <<"is"<<length<<"chars long";
}