#c #string #file #text #user-input
#c #строка #файл #текст #пользовательский ввод
Вопрос:
У меня возникли некоторые проблемы с сохранением текстового файла, созданного в окне консоли, в пользовательское местоположение, определенное пользовательским вводом. Я хочу, чтобы он принял строку, filepath
которая будет местоположением сохранения, и объединил ее со строкой, filename
которая будет именем текстового файла, выбранного пользователем. Например, так C:usersbobbertdesktopc .txt
затем я хочу иметь третью строку, которая была бы фактическим текстом для записи в c .txt файл. Вот мой код:
cout<<"Please enter a name for your file: "<<endl;
cin>>filename;
cout<<"Please enter a directory to save your file in: "<<endl;
cin>>filepath;
//user is now typing data into the text file
cin>>data;
//the data is now being grabbed and put into the "Data" string
FILE * pFile;
pFile = fopen (filepath.c_str() filename.c_str(),"a");
//trying to combine the users selected directory the selected filename here
if (pFile!=NULL)
{
fputs(data.c_str(), pFile);
//here i am trying to take the data of the .txt file
//string and put it into the new file
}
fclose (pFile);
Спасибо, что нашли время прочитать это! 🙂
Комментарии:
1. Для дальнейшего использования было бы лучше, если бы вы действительно описали, что не так. Вы никогда не задавали здесь вопрос.
Ответ №1:
filepath.c_str() filename.c_str()
строки не объединяются, поскольку они являются указателями на массивы символов, а не на объекты C std::string
. Вы просто [пытаетесь] выполнить арифметику над указателями.
Попробуйте:
std::string filename, filepath, data;
cout << "Please enter a name for your file: " << endl;
cin >> filename;
cout << "Please enter a directory to save your file in: " << endl;
cin >> filepath;
//user is now typing data into the text file
cin >> data;
//the data is now being grabbed and put into the "Data" string
ofstream fs((filepath "/" filename).c_str(), ios_base::app);
//trying to combine the users selected directory the selected filename here
if (fs)
fs << data;
Я заменил ваше использование C-style fopen
на объект stream C , исправил вашу проблему со строками и добавил обратную косую черту между filepath
и filename
(для безопасности на случай, если пользователь ее не напишет).
Обратите внимание, что вам все равно нужно выполнить .c_str()
обработку std::string
результата конкатенации при передаче готового пути в ofstream
конструктор, потому что iostreams были разработаны до библиотеки strings. Это просто отвратительный C -изм.
Комментарии:
1. 1, но на самом деле он не выполняет арифметику указателей, поскольку указатели не могут быть суммированы (эта строка, вероятно, вызвала бы ошибку компиляции).
2. @Matteo: Попытка * 🙂 То, что он не может, является, конечно, источником его проблем, и если бы он мог, то проблемы было бы просто немного сложнее обнаружить и отладить. Кстати, мы обычно говорим «строка», а не «row».
Ответ №2:
В истинном духе c
#include <iostream>
#include <fstream>
#include <string>
int main()
{
std::string filename, filepath, data;
std::cout << "Please enter a name for your file: " << std::endl;
std::cin >> filename;
std::cout <<" Please enter a directory to save your file in: " << std::endl;
std::cin >> filepath;
std::ofstream file((filepath "/" filename).c_str());
//std input is being copied to the file
file << std::cin.rdbuf();
file << std::flush;
file.close();
return 0;
}
В духе C объединить путь
{
char* fspec;
if (-1 == asprintf(amp;fspec, "%s/%s", filepath.c_str(), filename.c_str()))
{ perror("asprintf"); return 255; }
std::cout << fspec << std::endl;
free(fspec);
}
Мне было не совсем ясно, как вы потребуете, чтобы входные данные обрабатывались;
При желании вы можете прочитать его в буфер памяти, используя потоки строк многими способами, например
без потери пробелов:
std::stringstream ss;
ss << std::cin.rdbuf();
// OR
std::copy(std::istreambuf_iterator<char>(std::cin) ,
std::istreambuf_iterator<char>(),
std::streambuf_iterator<char>(ss));
…. и несколько альтернатив, которые удаляют пробелы:
std::copy(std::istream_iterator<std::string>(std:: cin),
std::istream_iterator<std::string>(),
std::stream_iterator<std::string>(ss));
bool my_isspace(char c) { return std::isspace(c); } // in namespace scope
std::remove_copy_if(std::istreambuf_iterator<char> (std::cin),
std::istreambuf_iterator<char>(),
std::streambuf_iterator<char>(ss), my_isspace);
Комментарии:
1. Эй, это здорово! Именно то, что я искал. Однако есть одна проблема: каждый раз первое слово вырезается. Например, я набираю «Привет, Салли» в консоли, в текстовом файле отображается «Салли». Также я использовал ctrl C для выхода out, потому что ввод не сработал (что хорошо, потому что мне нужно иметь возможность написать более одной строки) есть ли правильный способ выхода? Спасибо!
2. В моем коде нет слов, смотрите здесь . Я почти уверен, что вы оставили инструкцию stray
cin>>data
из своего старого кода? Компьютеры имеют привычку подчиняться вашим командам 🙂 Правильный способ выхода — EOF (Ctrl-D в UNIX / linux, Ctrl-Z в Windows)3. Конечно, я забыл удалить cin>>данные из моего старого кода. Теперь это работает, за исключением Ctrl-Z. Для меня он завершается только при нажатии Ctrl-C. Работает ли у вас Ctrl-z? Я использую 32-разрядную версию Windows 7.
4. Хотя я уверен, что изучение того, как управлять консольной клавиатурой Windows, не является целью вашего курса, я только что запустил старую виртуальную машину Windows, и вот: Ctrl-Z работает. Попробуйте это с
copy con: nul:
. Кстати, вы можете попробовать нажать клавишу F6, чтобы вставить Ctrl-Z, если ваша клавиатура работает
Ответ №3:
Завершает ли пользователь вводимую строку обратной косой чертой? Если нет, то ваш путь неверен.