Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Простой вопрос по консальному приложению

262
10 ноября 2004 года
Iktomy
1.2K / / 11.10.2004
Имеется в наличии Visual C++ 6.0 (+SP6), Win2k SP4 и консольное приложение на Си
Код:
#include <stdio.h>
#include <conio.h>

void main()
{
    char m_Text[500];
    printf("Введите текст: ");
    gets(m_Text);
    printf("Вы ввели %s\n", m_Text);
    getch();
}

Вопрос первый:
Размер массива m_Text указывается явно в начале программы, а хотелось бы сделать массив динамическим и определять его размер уже после ввода текста.
Вопрос второй:
Вместо "Введите текст" и "Вы ввели" отображается какая то херь нерусская. Хотя сам текст вводится\выводится вполне понятно и грамматически верно. Как бороться? В настройках компилятора тоже стоит русский - /l 0x419. Ставил English(USA) - ничерта не помогло
2
10 ноября 2004 года
squirL
5.6K / / 13.08.2003
Цитата:
Originally posted by Iktomy

Размер массива m_Text указывается явно в начале программы, а хотелось бы сделать массив динамическим и определять его размер уже после ввода текста.



:) у тебя в качестве параметра функции gets стоит указатель на строку. как ты думаешь, что получиться, если ты будешь определять размер буффера в который ты считываешь уже после считывания? :)
использование символьных массивов с заранее заданным размером - вполне нормальная практика в C. в С++ - можно использовать string.

301
10 ноября 2004 года
lord Kelvin
897 / / 08.11.2004
Динамически создавать массивы можна используя malloc (calloc + etc из alloc.h). Возможно тебе поможет такое рещение.

#include<stdio.h>
#include<alloc.h>

void my_gets(char *str)
{
char buf=malloc(80*25);
gets(buf);
str=malloc(strlen(buf));
strcpy(str,buf);
free(buf);
}

void main()
{
char *ptr;
my_gets(ptr);
printf("%s\n",ptr);
free(ptr);
}
2
10 ноября 2004 года
squirL
5.6K / / 13.08.2003
Цитата:
Originally posted by lord Kelvin
Динамически создавать массивы можна используя malloc (calloc + etc из alloc.h). Возможно тебе поможет такое рещение.

#include<stdio.h>
#include<alloc.h>

void my_gets(char *str)
{
char buf=malloc(80*25);
gets(buf);
str=malloc(strlen(buf));
strcpy(str,buf);
free(buf);
}

void main()
{
char *ptr;
my_gets(ptr);
printf("%s\n",ptr);
free(ptr);
}



утверждать не буду, но по моему - это те же яйца, только вид с нестандартной стороны. смысла в таком решении задачи не вижу ;)

301
10 ноября 2004 года
lord Kelvin
897 / / 08.11.2004
Цитата:
Originally posted by squirL


утверждать не буду, но по моему - это те же яйца, только вид с нестандартной стороны. смысла в таком решении задачи не вижу


Iktomy попросил динамическое выделение памяти под строку - он его получил. Хорошо так делать или нет - вопрос не ко мне. На счет яиц - сам бы я так писать не стал.;)

2
10 ноября 2004 года
squirL
5.6K / / 13.08.2003
Цитата:
Originally posted by lord Kelvin

Iktomy попросил динамическое выделение памяти под строку - он его получил. Хорошо так делать или нет - вопрос не ко мне. На счет яиц - сам бы я так писать не стал.;)



зачем давать заведомо глупое, (или скажем мягче - нехорошее) решение??? ты не стал бы так делать, так зачем советуешь другим? не проще объяснить челу - как правильнее?

292
10 ноября 2004 года
Matush
726 / / 14.01.2004
Другого нормального варианта кроме как считать строку в буфер заведомого размера, а потом перекинуть в переменную, которую сделать нужного размера, я не вижу.
Сам я делаю именно так.
Причем считывание в буфер заведомого размера защищает от превышения возможнонужного размера строки.
вот и все :)
3
10 ноября 2004 года
Green
4.8K / / 20.01.2000
Цитата:
Originally posted by Matush
Другого нормального варианта кроме как считать строку в буфер заведомого размера, а потом перекинуть в переменную, которую сделать нужного размера, я не вижу.
Сам я делаю именно так.
Причем считывание в буфер заведомого размера защищает от превышения возможнонужного размера строки.
вот и все :)



А как на счет потоков?

Код:
#include <string>
#include <iostream>

int main()
{
    std::string strText;

    std::cout << "Введите текст: ";
    std::getline(std::cin, strText);
    std::cout << "Вы ввели: " << strText << std::endl;

    return 0;
}
262
11 ноября 2004 года
Iktomy
1.2K / / 11.10.2004
Спасибо всем, что разъяснили мне, Фоме неверующему, что такое хорошо и что такое зашибися. Остановлюсь я все-таки на заданном размере строки. Но вот у меня возник еще вопрос: как преобразовывать из char в int или float, а если поточнее, то я выбираю из строки символы, все по порядку, и надо выяснить, есть ли среди символов числа. Я сразу делал так: создавал еще массив с символами от 0 до 9 плюс еще ‘.’ и ‘,’ (мало ли как там захотят при вводе дроби написатьJ). Но во-первых это вышло очччень гемморойно, а во-вторых – глючно. И я решил сделать по другому: разбивать строки по словам, а после проверять – является ли это слово числом или нет (читается бредово – но по-другому не умеюJ). Ну а потом вывести это число на экран.
Дык вот скажите мне, можно ли преобразовать char в численный тип, правильно ли я мыслю по поводу решения вообще или лучше мне выпить валерьянки и еще раз подумать.
И хоть кто ни будь скажет таки, как побороть каракули при выводе.
301
11 ноября 2004 года
lord Kelvin
897 / / 08.11.2004
Итак.
Является ли символ цифрой - проверяй isdigit, из ctype.h. Преобразования строки в число - atoi - в int, atol - в long, atof - в double. Вот. Только повнимательнее с ошибками.
А вот на счет каракуль - не знаю. Может в свойствах exe' шника шрифт поменять?
292
11 ноября 2004 года
Matush
726 / / 14.01.2004
На счет вывода нормального русского текста:
char str[128];
strcpy(str, "Текст по русски");
CharToOem(str, str);
printf(str);

Тут все описано:
MSDN->Platform SDK->Windows Base Service->General Library->String manipulation->String manipulation reference->String manipulation functions
3
11 ноября 2004 года
Green
4.8K / / 20.01.2000
Цитата:
Originally posted by lord Kelvin
Итак.
Является ли символ цифрой - проверяй isdigit, из ctype.h. Преобразования строки в число - atoi - в int, atol - в long, atof - в double. Вот. Только повнимательнее с ошибками.


А почему бы не использовать С++, чтоб не допускать потенциальных ошибок?

Код:
#include <iostream>
#include <string>
#include <sstream>

template <typename T>
std::string toString(T val)
{
    std::ostringstream oss;
    oss<< val;
    return oss.str();
}

template<typename T>
T fromString(const std::string& s)
{
  std::istringstream iss(s);
  T res;
  iss >> res;
  return res;
}


int main()
{
    std::string str = toString(5.56);
    float val = fromString<float>(str);

    std::cout << "str=" << str <<std::endl;
    std::cout << "val=" << val <<std::endl;

    return 0;
}


P.S. в fromString необходимо ввести проверку, что первый символ является числом:
Код:
template<typename T>
T fromString(const std::string& s)
{

  if( !isdigit(s.at(0)) ) return 0;


  std::istringstream iss(s);
  T res;
  iss >> res;
  return res;
}
527
11 ноября 2004 года
pavor
275 / / 28.09.2003
Цитата:
Originally posted by Green

А почему бы не использовать С++, чтоб не допускать потенциальных ошибок?

Код:
#include <iostream>
#include <string>
#include <sstream>

template <typename T>
std::string toString(T val)
{
    std::ostringstream oss;
    oss<< val;
    return oss.str();
}

template<typename T>
T fromString(const std::string& s)
{
  std::istringstream iss(s);
  T res;
  iss >> res;
  return res;
}


int main()
{
    std::string str = toString(5.56);
    float val = fromString<float>(str);

    std::cout << "str=" << str <<std::endl;
    std::cout << "val=" << val <<std::endl;

    return 0;
}


P.S. в fromString необходимо ввести проверку, что первый символ является числом:
Код:
template<typename T>
T fromString(const std::string& s)
{

  if( !isdigit(s.at(0)) ) return 0;


  std::istringstream iss(s);
  T res;
  iss >> res;
  return res;
}


А почему бы не использовать C чтобы не допускать фрагментации памяти?
Green, кстати ты не в курсе, где исправляют различные глюки и тупой код в STL, WTL. Я хочу написать им. Так, например, по моему при включении <map> выводится warning 4702, а со скольки warningами сделан ATL/WTL и они просто там дисабляться страшно сказать.

368
12 ноября 2004 года
rostyslav
629 / / 13.07.2004
Цитата:
Originally posted by Green

А почему бы не использовать С++, чтоб не допускать потенциальных ошибок?
...
...
...
[/CODE]


5.56 это альфа и омега рациональных чисел?
В начале топика вроде говорилось о вводе каких-то данных через клавиатуру...

Второй вариант fromString()
-8.92 он примет за float? Или переведет в 0?
Первый вариант принимает за -8.92.

3
12 ноября 2004 года
Green
4.8K / / 20.01.2000
Цитата:
Originally posted by rostyslav

5.56 это альфа и омега рациональных чисел?


Это пример использования.

Цитата:
Originally posted by rostyslav

В начале топика вроде говорилось о вводе каких-то данных через клавиатуру...


Ну... и в чем проблема?
Кто мешает черпать из потока std::cin ?

Цитата:
Originally posted by rostyslav

Второй вариант fromString()
-8.92 он примет за float? Или переведет в 0?
Первый вариант принимает за -8.92.


Код в P.S. не является рабочим применительно к отрицательным значениям, согласен.
Думаю, релизовать правильную проверку не составит большого труда?

Цитата:
Originally posted by pavor

А почему бы не использовать C чтобы не допускать фрагментации памяти?


Почему? Мы сейчас опять сцепимся по поводу С/С++.
Фрагментация памяти? Ты о чем? :)

Цитата:
Originally posted by pavor

Green, кстати ты не в курсе, где исправляют различные глюки и тупой код в STL, WTL. Я хочу написать им. Так, например, по моему при включении <map> выводится warning 4702, а со скольки warningами сделан ATL/WTL и они просто там дисабляться страшно сказать.


STL я заменил на STLPort c stlport.com, там же на форуме можно оставить сообщение о найденных недостатках.
А WTL лучше взять последний с SourceForge, там многое пофиксено. Там же можно указать/узнать о багах: http://sourceforge.net/projects/wtl/

368
12 ноября 2004 года
rostyslav
629 / / 13.07.2004
Цитата:
Originally posted by Green

Код в P.S. не является рабочим применительно к отрицательным значениям, согласен.


float val = fromString<float>(".2");
std::cout << "val=" << val <<std::endl;

тоже печатает не то что надо, хоть 0.2 > 0

Цитата:
Думаю, релизовать правильную проверку не составит большого труда?


Конечно. Достаточно убрать из второго варианта первую команду.

3
12 ноября 2004 года
Green
4.8K / / 20.01.2000
Цитата:
Originally posted by rostyslav

float val = fromString<float>(".2");
std::cout << "val=" << val <<std::endl;

тоже печатает не то что надо, хоть 0.2 > 0

Конечно. Достаточно убрать из второго варианта первую команду.


Вообще-то, класс fromString обладает большей универсальностью, чем переводить из строки в число, поэтому в первом варианте и нет проверки.
Но! Если говорить о переводе в число, то есть вероятность неправильного перевода в случае, если строка начинается с буквы.
Что касается .2, то следует согласовать написание чисел и уж потом вводить соотв. проверку, т.к. невозможно создать программу, которая отследила бы все возможные варианты записи.

262
12 ноября 2004 года
Iktomy
1.2K / / 11.10.2004
Ой хлопцы, чего то вы совсем разошлись, я прям виноватым себя чувствую. И от темы отошли немного.
Я тут поэкпирементировал с atoi, atof и проч. Но ничерта хорошего из этого не вышло. Поставим вопрос по другому, как таки проверить является ли набор символов числом или нет? Есть ли вообще такие способы. А то эти ato и сотоварищи просто конвертят символы буквенные во всякую бредятину. Лучше бы возвращали сообщение об ошибке. Может они это и делают, но по крайней мере в MSDN я ничего не накопал. Или может копал неглубоко.:(
А за CharToOem спасибочки, глюки исчезли. Только вот жаль, что простое консольное приложение, которое по идее и в ДОС должно компилися теперь затребовало Виндошный хедэр. Ну да черт с ним.
527
12 ноября 2004 года
pavor
275 / / 28.09.2003
Выполнение кода - вызов функции toString
Создание потока
создание объекта string при вызове str()
вызов конструктора копирования string для строки в теле главной функции
Вызов деструктора потока
вызов деструктора string для строки, созданной внутри тела функции
Вызов деструктора для string в теле главной функции при выходе из проги.

Два варианта оптимизации
1)посчитать сколько знаков и создать массив.

2)сделать нормальные операторы
template <typename T>
string &operator <<(string &str, T& t);
3
12 ноября 2004 года
Green
4.8K / / 20.01.2000
Цитата:
Originally posted by pavor
Выполнение кода - вызов функции toString
Создание потока
создание объекта string при вызове str()
вызов конструктора копирования string для строки в теле главной функции
Вызов деструктора потока
вызов деструктора string для строки, созданной внутри тела функции
Вызов деструктора для string в теле главной функции при выходе из проги.

Два варианта оптимизации
1)посчитать сколько знаков и создать массив.

2)сделать нормальные операторы
template <typename T>
string &operator <<(string &str, T& t);



Зачем?!
Зачем каждый раз изобретать велосипед именно для данного случая?
Почему бы не писать на ассемблере? Ничего лишнего.
Переписать все системные контролы, т.к. они делают много лишнего, переписать весь crt и т.д.
Зачем?!
Если у тебя настолько критичный код, пиши на ассме, т.к. даже на С в результат попадет много всего лишнего.

262
15 ноября 2004 года
Iktomy
1.2K / / 11.10.2004
Цитата:
Originally posted by Green

Почему бы не писать на ассемблере? Ничего лишнего.
Переписать все системные контролы, т.к. они делают много лишнего, переписать весь crt и т.д.


Боюсь на Асме это не совсем то что мне надо, мне нужен Си и только.
Да, я тут на выходных мозгами пораскинул, все проработал и поэтому сенкс всем, а я уж дальше сам.
Прошу товарища модератора считать тему закрытой!:!!!:

10
15 ноября 2004 года
Freeman
3.2K / / 06.03.2004
Цитата:
Originally posted by Iktomy
А за CharToOem спасибочки, глюки исчезли. Только вот жаль, что простое консольное приложение, которое по идее и в ДОС должно компилися теперь затребовало Виндошный хедэр. Ну да черт с ним.


Возможно я уже и опоздал, но вдогонку два соображения:

- Консольное приложение Win32 не имеет ничего общего с DOS - это обычная виндовая прога, просто интерфейс у нее такой. Поэтому вполне логично, что компилироваться она должна с учетом зависимости от платформы.

- Если вывод на экран делается файловыми фуккциями, тебе могут помочь AreFileApisANSI, SetFileApisToANSI, SetFileApisToOEM. Тогда не понадобится каждый раз переводить строку в набоор символов OEM самому.

Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог