2016-01-11 2 views
0

Недавно я узнал о функциональности ##, которую я могу определить в начале моего кода. Я пытаюсь скомпилировать следующий код:C++ help concatenating TCHAR

#include <windows.h> 
#include <tchar.h> 
#include <iostream> 
#include <stdio.h> 
#include <string> 

#define paste(x,y) *x##*y 

int main() 
{ 

TCHAR *pcCommPort = "COM"; 
TCHAR *num = "5"; 

cout << paste(pcCommPort,num); 
return 0; 
} 

и я получаю следующее сообщение об ошибке:

expression must have arithmetic or unscoped enum type 

это не нравится тот факт, что я использую указатели в моей «определить» вставить строку , Без каких-либо указателей он просто вернет переменную «pcCommPort5». я хочу «COM5».

Я попытался _tcscat, strcat, strcat_s, визуальная студия не нравится ни один из них ....

+0

Не используйте препроцессор, если вам это не нужно. Он выполняется перед обычной компиляцией (как намечено ее именем), а не во время выполнения. – chris

+0

'_tcscat' должен работать, вам просто нужно предоставить буфер для записи подходящего размера. Создайте третью переменную как массив 'TCHAR', используйте' _tcscpy', чтобы скопировать первую строку в нее, а затем используйте '_tcscat', чтобы добавить вторую строку. Или используйте 'std :: basic_string ' вместо этого и сэкономьте себе много горя. Или забудьте о 'TCHAR' целиком, так как вы, вероятно, никогда не будете использовать его как« char », и используйте' std :: wstring'. –

+0

Ой, не обращая внимания на последнюю часть моего комментария, так как вы успешно назначаете нормальную строку 'char' для переменной, вы должны быть настроены так, что' TCHAR' является 'char'. Это означает, что вы должны использовать 'std :: string'. –

ответ

1

## не сцепить произвольные вещи (особенно не строки). Что он делает, это объединяет символы вместе в синтаксическом анализаторе в один символ.

Давайте удалим один из тех *, чтобы увидеть, что происходит:

#include <iostream> 

#define TO_STRING_HELPER(x) #x 
#define TO_STRING(x) TO_STRING_HELPER(x) 
#define CONCAT(x, y) *x##y 

int main() { 
    char *pcCommPort = "COM"; 
    char *num = "5"; 
    std::cout << TO_STRING(CONCAT(pcCommPort, num)) << std::endl; 
} 

Output:

*pcCommPortnum 

Что CONCAT делает в этом коде:

  1. Развернуть x в pcCommPort и y в num. Это дает выражение *pcCommPort##num.
  2. Объедините два символа pcCommPort и num в новый символ: pcCommPortnum. Теперь выражение равно *pcCommPortnum (помните, что последняя часть (pcCommPortnum) - все один символ).
  3. Завершить оценку полного макроса как *, за которым следует символ pcCommPortnum. Это становится выражением *pcCommPortnum. Помните, что это два разных символа: * и pcCommPortnum. Два символа следуют один за другим.

Если бы мы должны были попытаться использовать *x##*y, что компилятор делает это:

  1. Развернуть x в pcCommPort и y в num. Это дает нам выражение *pcCommPort##*num.
  2. Объединить два символа pcCommPort и * в новый символ: pcCommPort*.
  3. Здесь препроцессор обращается к ошибке: единственный символ pcCommPort* не является допустимым токеном предварительной обработки. Помните, что на данный момент это не два отдельных символа (это не два символа pcCommPort, за которым следует *). Это один один символ (который мы называем token).

Если вы хотите объединить две строки, вам будет лучше с помощью std::string.Вы не можете делать то, что вы пытаетесь сделать с препроцессором.

* Примечание, однако, что последовательные строковые литералы будут объединены вместе компилятором (т.е. "COM" "5" будет объединено в одну строку "COM5" компилятора). Но это работает только со строковыми литералами, поэтому вам нужно будет #define pcCommPort "COM" и #define num "5", после чего вы можете сделать pcCommPort num (без каких-либо дополнительных макросов), и компилятор будет оценивать его в строке "COM5". Но если вы действительно не знаете, что делаете, вам действительно нужно использовать std::string.

+0

Это не работает. Просто попробуйте '#define paste pcCommPort num' –

+0

@BarmakShemirani: Что значит« что не работает »? Конечно, это не сработает. Невозможно сделать то, что хочет OP с помощью макросов. Кроме того, ваше предложение не работает. – Cornstalks

+0

О, извините, я думал, что 'pcCommPort' и' num' были предопределенными макросами –

 Смежные вопросы

  • Нет связанных вопросов^_^