Страницы

Поиск по вопросам

Показаны сообщения с ярлыком console. Показать все сообщения
Показаны сообщения с ярлыком console. Показать все сообщения

понедельник, 13 апреля 2020 г.

Unicode при записи в файл

#windows #unicode #console #visual_studio #cpp

                    
Мне нужно создать консольное приложение, которое 

Считывало бы введённые пользователем символы: как англоязычные, так и русскоязычные.
Выводила бы эти символы на экран в консоль.
Записывала бы эти символы в файл.

С первым и вторым пунктом, как убрать кракозябры, я разобрался следующим образом:


Подключил #include 


Весь вывод стал пропускать через функцию ToRus т.е. cout<< ToRus(L"Почему всё так
сложно!")


Вот сама функция:
char *ToRus(wchar_t *str) {   
static char s[1024];   
CharToOem(LPCWSTR(str), s);    
return s; }

Но осталась проблема 3-м пунктом - с выводом в файл. В файл по-прежнему выводятся
кракозябры. Подскажите, пожалуйста, как решить проблему, как сделать так, чтобы в файл
нормально выводилась? Может вообще, как-то по-другому нужно было делать?    


Ответы

Ответ 1



Нашёл! Вот вам статья: http://www.codeproject.com/Articles/4563/Upgrading-an-STL-based-application-to-use-Unicode. (Не смотрите часть с tstream/TCHAR, вам нужно просто wstream.) Или то же здесь: http://forums.codeguru.com/showthread.php?457106-Unicode-text-file&p=1741409#post1741409. Проблема в том, что обыкновенный wfstream принимает Unicode-строки, а вот пишет их как не-Unicode. Но его можно заставить. Вот вам вкратце описание, как. Первый шаг: создаёте «пустой» конвертер. В обычном случае wchar_t* конвертируется с потерями в обычные символы, но нам надо эту конвертацию отключить. Код конвертера: #include #include #include #include #include typedef std::codecvt null_wcodecvt_base; class null_wcodecvt : public null_wcodecvt_base { public: explicit null_wcodecvt(size_t refs = 0) : null_wcodecvt_base(refs) {} protected: virtual result do_out(mbstate_t&, const wchar_t* from, const wchar_t* from_end, const wchar_t*& from_next, char* to, char* to_end, char*& to_next) const { size_t len = (from_end - from) * sizeof(wchar_t); memcpy(to, from, len); from_next = from_end; to_next = to + len; return ok; } virtual result do_in(mbstate_t&, const char* from, const char* from_end, const char*& from_next, wchar_t* to, wchar_t* to_end, wchar_t*& to_next) const { size_t len = (from_end - from); memcpy(to, from, len); from_next = from_end; to_next = to + (len / sizeof(wchar_t)); return ok; } virtual result do_unshift(mbstate_t&, char* to, char*, char*& to_next) const { to_next = to; return noconv; } virtual int do_length(mbstate_t&, const char* from, const char* end, size_t max) const { return (int)((max < (size_t)(end - from)) ? max : (end - from)); } virtual bool do_always_noconv() const throw() { return true; } virtual int do_encoding() const throw() { return sizeof(wchar_t); } virtual int do_max_length() const throw() { return sizeof(wchar_t); } }; Теперь, надо ещё переопределить endl. std::wostream& wendl(std::wostream& out) { out.put(L'\r'); out.put(L'\n'); out.flush(); return out; } А вот и пример использования. Не забудьте про BOM (такая штука в начале файла, может и не понадобиться, если не под Windows). const wchar_t UTF_BOM = 0xfeff; int main() { // заводим файл std::wfstream file; // инстанциируем пустой конвертер null_wcodecvt wcodec(1); std::locale wloc(std::locale::classic(), &wcodec); // сообщаем файлу, что он должен использовать этот конвертер, // а не стандартный. обязательно делаем это _до_ открытия файла file.imbue(wloc); // открыли файл, обязательно как binary, чтобы никакой самодеятельности // от стандартной библиотеки file.open("data.txt", std::ios::out | std::ios::binary); if (!file) { // если текст русский, надо прогнать через `ToRus` std::cerr << "Failed to open data.txt for writing" << std::endl; return 1; } // записали в начало файла BOM file << UTF_BOM; // записали текст file << L"Я тоже не знаю, почему в C/C++ всё так сложно." << wendl; // закрыли файл file.close(); // фсё! return 0; }

четверг, 2 апреля 2020 г.

Как узнать символ в консоли под курсором?

#c_sharp #console

                    
Например в консоли есть символ "#" в координатах (0,0)
как узнать что там символ "#" ,а не "?"
    


Ответы

Ответ 1



Штатные средства класса Console не позволяют читать напрямую из выходного буфера, хотя WinAPI, поверх которого работают методы Console, такое позволяет. Следовательно придется импортировать нужные функции руками. Выглядеть будет как-то так: class Program { [StructLayout(LayoutKind.Sequential)] struct COORD { public short X; public short Y; } // http://pinvoke.net/default.aspx/kernel32/ReadConsoleOutputCharacter.html [DllImport("kernel32.dll", SetLastError = true)] static extern bool ReadConsoleOutputCharacter( IntPtr hConsoleOutput, [Out] char[] lpCharacter, int nLength, COORD dwReadCoord, out int lpNumberOfCharsRead ); // http://pinvoke.net/default.aspx/kernel32/GetStdHandle.html [DllImport("kernel32.dll", SetLastError = true)] static extern IntPtr GetStdHandle( int nStdHandle ); static void Main() { //выводим символ Console.SetCursorPosition(10, 10); char outChar = 'K'; Console.Write(outChar); //читаем символ char[] readBuffer = new char[1]; int readCount; ReadConsoleOutputCharacter(GetStdHandle(-11), readBuffer, 1, new COORD() { X = 10, Y = 10 }, out readCount); Console.SetCursorPosition(0, 0); Console.WriteLine($"{readBuffer[0] == outChar}"); Console.ReadKey(false); } } Демка построена на основе примеров кода с pinvoke.net с небольшими модификациями.

воскресенье, 8 марта 2020 г.

Как корректно отобразить переменную double в java

#java #console #double


При нахождении скорости целыми числами вывод отображается корректно, но если задать,
допустим время 7,6 , то компилятор пишет ошибку    

import java.util.*;
import java.lang.*;
import java.io.*;
public class Speed {
  public static void main(String[] args) {
    Scanner sc = new Scanner(System.in);
    // TODO Auto-generated method stub
    System.out.println("Давай-ка посчитаем твою скорость");
    System.out.println("Введи время и дистанцию");
    System.out.println("Введи дистанцию в метрах");

    double distance = sc.nextDouble();
    System.out.println("Хорошо, теперь время");
    double time = sc.nextDouble();
    System.out.println("");
    double speed = ((distance/time)*3600/1000);
    double speed1 = (distance/time); 
    System.out.format("Твоя скорость равна ");
    System.out.format("%.2f", speed);
    System.out.println(" км/ч");
    System.out.print("или ");
    System.out.format("%.2f", speed1);
    System.out.print(" м/с");
  }
}

    


Ответы

Ответ 1



Следует задать время через точку: например, 7.6 Кроме того, можно настроить локаль, чтобы можно было задавать время через запятую, но это, как говорится, совсем другая история.

вторник, 25 февраля 2020 г.

GUI для консольного приложения (выполнение команд после запуска)

#c_sharp #gui #console #execute


Добрый день. 
Столкнулся с такой проблемой, решил создать GUI для консольного приложения, запускаю
его так.
MyProc.StartInfo.FileName = filename;
MyProc.StartInfo.Arguments = arguments;
MyProc.StartInfo.UseShellExecute = false;
MyProc.StartInfo.RedirectStandardOutput = true;
MyProc.Start();
if (waitforexit)
    MyProc.WaitForExit();

Запускается приложение с ключом без проблем, но как передать этому приложению ещё
одну команду? Запускать заново - не вариант, т.к приложение запускается таким образом
cProgram.exe file_name

И дальше идет выполнение команд внутри cProgram
(cProgram) write_some_comand

Как быть?    


Ответы

Ответ 1



Обмениваться с приложением через пайп. Вот пример (delphi): консольный редирект в обе стороны. Еще лучше пример тут: Creating a Child Process with Redirected Input and Output. Но это WinAPI.

Ответ 2



Послать в консоль команду: myProc.StandardInput.WriteLine("write_some_comand\r\n"); myProc.StandardInput.Flush(); Можно также создать процесс, не показывая самой консоли: myProc.StartInfo.CreateNoWindow = true; myProc.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;

Ответ 3



Что-то мне подсказывает winapi (sendmessage, postmessage). Общий алгоритм таков: ищете название окна (тоже winapi FindWindow), получаете handle окна и по это handle отправляете message (можно стандартные, WM_CLOSE, etc.). Или же делаете свой, кастомный message-list-parameters.

пятница, 7 февраля 2020 г.

Почему сравнения возвращают различные результаты?

#c_sharp #console #if


static bool Compare0()
{
    return new byte() == new byte();
}

static bool Compare1()
{
    return new byte[0] == new byte[0];
}

static void Main()
{
    Console.WriteLine(Compare0());
    Console.WriteLine(Compare1());

    Console.ReadKey();
}


Почему Compare0() возвращает True, а Compare1() - False?
    


Ответы

Ответ 1



Конструкция new byte() создает экземпляр типа byte, проинициализированный нулем. byte -- это структура, а следовательно, это значимый тип. По умолчанию все значимые типы сравниваются по значению. Поскольку два экземпляра проинициализированы одинаковым значением, Compare0() возвращает True. Конструкция new byte[0] создает пустой массив типа byte. Массив -- это ссылочный тип. По умолчанию экземпляры ссылочных типов равны, только если их ссылки равны, т.е. экземпляры указывают на один и тот же объект. Поскольку два экземпляра массива -- это два разных объекта в памяти, Compare1() возвращает False. Подробнее о значимых и ссылочных типах можно почитать в этом ответе.

воскресенье, 2 февраля 2020 г.

Python: 'charmap' codec can't decode byte 0x98

#python #windows #python_3x #console #unicode


Добрый день
Считываю utf8-файл и вывожу в консоль. При попытке вывести букву "И" возникает ошибка:

File "I:\ProgramFile\Anaconda\lib\encodings\cp1251.py", line 15, in decode  
    return codecs.charmap_decode(input,errors,decoding_table)  
UnicodeDecodeError: 'charmap' codec can't decode byte 0x98 in position 1: character
maps to < undefined >


Воспроизводится на вот таком примере:

test_text_1 = "Задача\n"
test_text_2 = "Итератор"

file = open('temp.txt', 'w', encoding='utf-8')
file.write(test_text_1)
file.write(test_text_2)
file.close()

text = open('temp.txt', 'rb')

for byte_code in text:
    print(byte_code.strip())
    test_text = byte_code.decode('cp1251')
    print(test_text.strip())


Первое слово выводится нормально, а на втором - ошибка. Никак не могу найти способ
побороть проблему.

UPD: Видимо я описал проблему слишком широко, исправляюсь:

Как конвертировать "И" из utf-8 в cp1251? Для "А" всё работает, а для "И" - нет.

Код:

byte1 = 'А'.encode('utf-8')
byte2 = 'И'.encode('utf-8')
print(byte1, byte2)
test1 = byte1.decode('cp1251')
print(test1)
test2 = byte2.decode('cp1251')
print(test2)

    


Ответы

Ответ 1



Чтобы напечатать файл, содержащий текст в utf-8 кодировке, в консоль (аналог type filename в cmd.exe) в Питоне: #!/usr/bin/env python3 import shutil import sys with open(filename, encoding='utf-8') as file: shutil.copyfileobj(file, sys.stdout) Если хочется напечатать Юникодные символы, которые непредставимы в chcp кодировке (OEM code page), то см. Как из Python вывести на Windows-консоль строку в Юникоде?

Ответ 2



Если у вас файл записан в кодировке utf-8, то и декодировать нужно из кодировки utf-8: ... for byte in text: print(byte.strip()) text = byte.decode('utf-8') print(text.strip()) Результат: b'\xd0\x97\xd0\xb0\xd0\xb4\xd0\xb0\xd1\x87\xd0\xb0' Задача b'\xd0\x98\xd1\x82\xd0\xb5\xd1\x80\xd0\xb0\xd1\x82\xd0\xbe\xd1\x80' Итератор Когда вы записываете текст в файл в какой-то кодировке, вы фактически превращаете внутреннее представление текста в байты в указанной кодировке. Чтобы правильно декодировать эти байты обратно во внутреннее представление, при декодировании нужно указать ту же кодировку, что и при записи.

среда, 29 января 2020 г.

Как вывести сообщение в консоль из приложения Windows Forms?

#c_sharp #winforms #console


Приложение может запускаться с параметрами. Есть необходимость вывести хелп с параметрами
в этой же консоли, где было запущено приложение, если пользователь ошибся, скажем так.
Как при запуске приложения в этой же консоли вывести сообщение?

    


Ответы

Ответ 1



Проблема в том, что cmd.exe не обрабатывает вывод приложений с графическим интерфейсом. При запуске оболочка проверяет флажок в заголовке исполняемого файла, и если приложение оконное, то оно запускается не блокируя консоль. После этого можно запустить другое приложение, выполнять команды, либо вовсе закрыть окно консоли. Соответственно, если после этого в консоли будут выводиться сообщения, то будет неясно от какого процесса они исходят. Предлагаю рассмотреть альтернативные варианты: Выводить сообщение об ошибке в графическом интерфейсе. Раз все приложение оконное, то и сообщение логично показывать в интерфейсе. С помощью Win32 присоединять консольный вывод к родительскому процессу через AttachConsole и насильно писать в него: //импорт функции [DllImport("kernel32.dll")] static extern bool AttachConsole(int dwProcessId); //присоединяемся к родительскому процессу AttachConsole(-1) //пишем в консоль Console.WriteLine("Some message"); Это будет выглядеть странно, особенно если в консоли будет запущен другой процесс. Так же если понадобится перенаправление потока вывода, то его придется реализовывать самому. Сделать приложение консольным (изменить тип вывода в настройках проекта Visual Studio). В этом случае будет работать вывод в консоль. Недостаток в том, что окно консоли появится даже при запуске в проводнике. Консоль можно скрывать с помощью ShowWindow, но полностью избежать его появления не получится.

Ответ 2



Как вариант можно создать новую консоль AllocConsole //импорт функции [DllImport("kernel32.dll")] static extern bool AllocConsole(); //.... // Присоиденить консоль AllocConsole(); и перед выводом её один раз вызвать. Будет создана новая консоль. (Одна консоль на один процесс, т.е. если вызвать из процесса повторно - две не будет). Если нужно таки писать в родительскую консоль, то можно соиденить AttachConsole и AllocConsole например так [DllImport("kernel32.dll")] static extern bool AttachConsole(int dwProcessId); [DllImport("kernel32.dll")] static extern bool AllocConsole(); // if (!AttachConsole(-1)) AllocConsole (); но тогда может возникнуть "конфликт" - два приложения будут писать в одну консоль. Но если обе будут выводить "законченые" (всегда заканчивающиеся переводом каретки, например) и "простые" (без атрибутов цветов очистки экрана и т п) предложения - то возможно не будут мешать друг другу.

вторник, 28 января 2020 г.

Цвет текста в консоли C#

#c_sharp #console


Как изменить цвет выводимой строки/символа в консоли в C#?    


Ответы

Ответ 1



Console.ForegroundColor = ConsoleColor.Green; // устанавливаем цвет Console.WriteLine("..."); Console.ResetColor(); // сбрасываем в стандартный

четверг, 23 января 2020 г.

TCP мониторинг подключения приложения

#c_sharp #console


Делаю консольное приложение, которое должно проверять подключение к определенному
IP и выполнять определенные действия. Как мониторить такое подключение?  Тут выводится
список всех исходящих, как отфильтровать и оставить только одно?

static void ListAvailableTCPPort(ref ArrayList usedPort)
    {
        IPGlobalProperties ipGlobalProperties = IPGlobalProperties.GetIPGlobalProperties();
        TcpConnectionInformation[] tcpConnInfoArray = ipGlobalProperties.GetActiveTcpConnections();
        IEnumerator myEnum = tcpConnInfoArray.GetEnumerator();

        while (myEnum.MoveNext())
        {
            TcpConnectionInformation TCPInfo = (TcpConnectionInformation)myEnum.Current;
            Console.WriteLine("{0}", TCPInfo.RemoteEndPoint);
            usedPort.Add(TCPInfo.LocalEndPoint.Port);
        }
    }

    public static void Main()
    {
        ArrayList usedPorts = new ArrayList();
        ListAvailableTCPPort(ref usedPorts);
        Console.ReadKey();
    }     

    


Ответы

Ответ 1



Если вам необходимо проверять подключение к определенному IP-адресу,то вы должны фильтровать 1. поле RemoteEndPoint - указывает на IP-адрес и порт TCP-соединения, который вас интересует 2. У подключения должно быть состояние(State)- Established, которое означает что соединение установлено и данные могут быть отправлены. Вот пример кода: static void SearchAvailableTCPConnection(ref ArrayList usedPort, string searchAddress, int searchPort) { IPGlobalProperties ipGlobalProperties = IPGlobalProperties.GetIPGlobalProperties(); IPEndPoint filterEndpoint = new IPEndPoint(IPAddress.Parse(searchAddress), searchPort); TcpConnectionInformation tcpConnInfoArray = ipGlobalProperties.GetActiveTcpConnections().Where(g => g.RemoteEndPoint.Equals(filterEndpoint) && g.State ==TcpState.Established).FirstOrDefault(); if (tcpConnInfoArray != null) { Console.WriteLine("Port {0} {1} {2} ", tcpConnInfoArray.LocalEndPoint, tcpConnInfoArray.RemoteEndPoint, tcpConnInfoArray.State); } } private static void Main(string[] args) { ArrayList usedPorts = new ArrayList(); SearchAvailableTCPConnection(ref usedPorts, "192.168.0.2", 8090); Console.ReadKey(); } На экран будет выведено сообщение только в том случае, если у нас есть активное TCP-соединение с IP-адресом 192.168.0.2 по порту 8090. Для конвертации строки IP-адреса в класс IPAddress, используем статическую функцию этого класса Parser.

воскресенье, 12 января 2020 г.

отладочная консоль и windows 10

#cpp #console #windows_10


Раньше, когда я не перешел на "вин 10", я всегда использовал в своих программах вот
такой простенький код для создания консоли в не консольных приложениях(код работал
в вин 7,8,8.1):

void createConsole()
{
    setlocale(0, "Russian");
    int hConHandle;
    long lStdHandle;
    FILE *fp;
    AllocConsole();
    lStdHandle = (long)GetStdHandle(STD_OUTPUT_HANDLE);
    hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
    fp = _fdopen(hConHandle, "w");
    *stdout = *fp;
    setvbuf(stdout, NULL, _IONBF, 0);
}


Выводил в консоль данные с помощью обычного "printf", далее я перешел на вин 10 и
испробовал скомпилировать свой проект на этой платформе - со старым кодом. К моему
удивлению в не консольном приложении нечего в консоль не вывелось, а в консольном посредством
функции "printf" вывелось - но я не смог вывести русский шрифт не смотря на то, что
я задал кириллицу "setlocale(0, "Russian");". Далее погуглив на счет кодировки я все
же смог выставить "русскую кодировку" в консольном приложении:

//Устанавливаем русский язык
    if (system("chcp 1251")) {
        message("Не удалось установить русский язык в консоле!");
    }

    SetConsoleCP(1251);// установка кодовой страницы win-cp 1251 в поток ввода
    SetConsoleOutputCP(1251); // установка кодовой страницы win-cp 1251 в поток вывода
    setlocale(LC_ALL, "Russian");


Проблема заключалась в следующем, мне консоль очень нужна в "не консольном" приложении
и погуглив я нашел другой код для создания и вывода данных в консоль на "msdn":

HANDLE handle;
void createConsole(){
AllocConsole();
handle = GetStdHandle(STD_OUTPUT_HANDLE);
}

bool write(std::string description, ...)
{
    char buf[1024];
    memset(buf, 0, sizeof(buf));

    va_list vaList;
    va_start(vaList, description);
    vsprintf_s(buf, (description + "\n").c_str(), vaList);
    va_end(vaList);

    if (WriteConsoleA(handle, buf, strlen(buf), 0, 0) == 0) {

        return false;
    }

    return true;
}


Консоль работает- все данные выводятся - но я не могу выводить русские символы в
консоль, даже этот код не помогает и не могу выводить информацию через "printf":

//Устанавливаем русский язык
        if (system("chcp 1251")) {
            message("Не удалось установить русский язык в консоле!");
        }

        SetConsoleCP(1251);// установка кодовой страницы win-cp 1251 в поток ввода
        SetConsoleOutputCP(1251); // установка кодовой страницы win-cp 1251 в поток
вывода
        setlocale(LC_ALL, "Russian");


Собственно вопросы:


Почему в вин 10 перестал работать старый код для создания консоли?
Почему я не могу выводить кириллицу в новую консоль и может ли это зависеть от языкового
пакета установленного на мою винду 10?
Почему не могу выводить данные через printf в не консольном приложении?


Так как я начинающий программист, хотелось услышать мнение профи о том нужна ли вообще
отладочная консоль и если нет то что тогда используют профи или может я не правильно
работаю с консолью, как вообще нужно делать правильно и грамотно?
    


Ответы

Ответ 1



О том как выводить русский текст в консоль написано тут - Русский язык в консоли. Однако, судя по всему Вы используете консоль только для логов. В Windows для этого есть система отладочного вывода, а именно функция OutputDebugStringW, вывод которой можно смотреть в отладчике, или в утилите DebugView. Способ, который используется в промышленном программировании - это библиотеки логов. Развитые системы логирования поддерживают различные приемники логов, в т.ч. stdout/stderr и OutputDebugString.

Не запускается Java из консоли

#java #windows #console


При попытке запуска из консоли java, получаю ответ, "java" не является внутренней
или внешней командой, исполняемой программой или пакетным файлом. Переменная %JAVA_HOME%
установлена. java не стартует, даже если перейти в папку где лежит она. При этом если
прописать java.exe с любого местоположения, все работает. Как сделать так, что бы из
консоли можно было запустить не только java.exe, но и без указания расширения?
    


Ответы

Ответ 1



Проверьте содержимое переменной окружения PATHEXT для этого можно в той же консоли прописать echo %PATHEXT%. В выводе консоли вы должны увидеть список поддержимавемых расширений. Проверьте наличие .EXE, если такого расширения по какой то причине нету, добавьте его: set PATHEXT=%PATHEXT%;.EXE Если переменной нету, не спешите добавлять ее, убедитесь, что в переменных среды пользователя не определена такая переменная. Если такая переменная заведена в переменных пользователя, то вероятно лучше ее удалить. И тогда все заработает.

Ответ 2



Нажми мой компьютер->свойства->дополнительные параметры системы->дополнительно->переменные среды и в переменную Path допиши путь до своей jdk(jre) папка bin

пятница, 10 января 2020 г.

Форматирование вывода данных в консоли

#c_sharp #console #консоль




Как красиво вывести числа в несколько столбцов, чтобы они не скакали?

Код:

for (int i = 0; i < 1000; i++)
{
    if (i % 3 == 0 || i % 5 == 0)
    {
        Console.Write(i + "  |  ");
        sum += i;
    }
}

    


Ответы

Ответ 1



Попробуйте следующий код: int sum = 0; int count = 0; for (int i = 0; i < 1000; i++) { if (i % 3 == 0 || i % 5 == 0) { Console.Write("{0, 7} | ", i); sum += i; count++; if (count == 8) { count = 0; Console.WriteLine(); } } } Обратите внимание на следующее: Для выравнивания выдачи чисел используется строка формата {0, 7}. Подробнее: MSDN Для сохранения столбцов от строки к строке, после каждых 8 чисел выдается перевод строки: Console.WriteLine().

Как закрыть консоль после выполнения приложения?

#c_sharp #console #selenium #selenium_webdriver


Приложение Selenium, после выполнения консоль остается на экране. Выкинул все из
кода, оставил только инициализацию и закрытие драйвера - все по-прежнему. Что делать?

using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using System;

namespace Myspace
{
    class Program
    {
        static void Main(string[] args)
        {
            IWebDriver driver = new ChromeDriver();

            driver.Close();

        }
}

    


Ответы

Ответ 1



Попробуйте так: using OpenQA.Selenium; using OpenQA.Selenium.Chrome; namespace ConsoleApp4 { public class Program { private static void Main() { IWebDriver driver = new ChromeDriver(); driver.Quit(); } } } Похоже что это баг, на их баг-трекере баг заведен. WebDriver.close() does not close browser window UPD: Кстати если использовать оператор using то всё закрывается корректно: private static void Main() { using (IWebDriver driver = new ChromeDriver()) { } //driver.Quit(); } Потому что метод Dispose как раз использует операцию Quit: protected virtual void Dispose(bool disposing) { try { this.Execute(DriverCommand.Quit, null); } /*...*/ }

понедельник, 6 января 2020 г.

Ровная таблица в консоли

#c_sharp #console #консоль


Требуется вывести в консоли ровную таблицу.
В данный момент решил это с помощью:

Console.Write("{0, -20}|", text);


Этим кодом я задал минимальное количество символов в столбце, но если символов будет
>20 - всё сломается.
Как обрезать вывод, если строка больше 20-ти символов?
    


Ответы

Ответ 1



В два приёма, разумеется. Собрать все строки вывода, выяснить максимальную длину. На основе максимальной длины сформировать форматную строку. Выводить через неё. В вашем случае вместо вывода у вас будет var column1 = new List(); column1.Add(text); А когда все строки будут добавлены, то var maxWidth = column1.Max(s => s.Length); var formatString = string.Format("{{0, -{0}}}|", maxWidth); foreach (var s in column1) { Console.Write(formatString, s); // тут наверное остальные колонки Console.WriteLine(); }

Ответ 2



Можно написать вспомогательный метод-расширения: public static class StringHelper { public static string Shorten(this string str, int value) { return value > 3 && str.Length > value ? str.Substring(0, value - 3) + "..." : str; } } который будет добавлять многоточие, если длина строки больше, чем value. Пример использования: Console.Write("{0, -20} ", text.Shorten(20));

Ответ 3



Решил проблему таким образом: if (element.Value.Length >= 20) { Console.Write("{0, -20}|", element.Value.Substring(0, 17) + "..."); } else { Console.Write("{0, -20}|", element.Value); } Спасибо @Ev_Hyper за помощь!

суббота, 4 января 2020 г.

console.log('hello',)

#javascript #windows #console #браузер


Не знал как назвать, кто придумает по умнее, буду признателен.
Проблема в том, что PhpStorm не подчеркнул и я упустил из виду:

console.log('hello',)

Данная конструкция роняла сайт на windows машинах, когда на mac все работало.
Не знаю как искать, но как по спецификации, допускается ли такое?  

По мне дак вполне нормально, вторая переменная undefined.
    


Ответы

Ответ 1



Давайте откроем стандарт языка ECMA-262 7-редакция от июня 2016. Смотрим как вызываются у нас функции 12.3.4 Function Calls. Как видим при вызове функции ей передается объект Arguments. Который определяется следующим образом. Arguments[Yield] : ( ) ( ArgumentList[?Yield] ) То есть он может быть либо пустым, либо передаваться как ArgumentList. ArgumentList : AssignmentExpression ArgumentList , AssignmentExpression Как видим список состоит из значений AssignmentExpression, которые разделены запятыми. Тут начинается самое сложное в стандарте, так как AssignmentExpression это целая куча различных вариантов значений. AssignmentExpression: ConditionalExpression YieldExpression ArrowFunction LeftHandSideExpression LeftHandSideExpression AssignmentOperator AssignmentExpression AssignmentOperator : one of *= /= %= += ‐= <<= >>= >>>= &= ^= |= **= То есть мы может указывать просто кучу всяких видов параметров: условные выражения, стрелочные функции, различные комбинации выражений, итераторы и многое другое. Но в общем-то нас интересует простейший вариант: LeftHandSideExpression. LeftHandSideExpression: NewExpression CallExpression Дальше идет целая вакханалия ссылок. Но в итоге все сводится либо к различным выражениям, либо в нашем случае к простейшим IdentifierName и Identifier. А они в свою очередь имеют такое определение: IdentifierName :: IdentifierStart IdentifierName IdentifierPart IdentifierStart :: UnicodeIDStart $ _ \ UnicodeEscapeSequenc То есть в любом случае должны быть хотя бы одна буква Юникода и таким образом AssignmentExpression не может состоять из пустоты. Там обязательно должно идти хоть что-то, иначе было бы в стандарте AssignmentExpression помечен опционально (opt) для ArgumentList. P.S. - И пусть потом кто-то попробует сказать, что стандарты это легко.

вторник, 31 декабря 2019 г.

Как делается псевдографический интерфейс в консоли?

#cpp #console


Решил создать консольный файловый менеджер и оформить его наподобие FARa.

Какие функции и библиотеки надо использовать, да и с чего вообще нужно начинать?
    


Ответы

Ответ 1



Вам нужны функции управления консолью. Поскольку C++ предоставляет лишь потоковый ввод-вывод (а этого не достаточно для ваших целей), вам придётся отказаться от использования cin/cout, и управлять консолью напрямую. Здесь, к сожалению, вам придётся разделить ваш Windows- и Linux-специфический код. Под Windows вам нужны консольные функции WinAPI. Наверное, проще всего будет просто напрямую обращаться к консольному буферу, который предоставляет символы на экране как просто прямоугольный массив из символов и их атрибутов. Под Linux- (и вообще Unix-)платформой вам понадобится библиотека ncurses, которая предоставляет аналогичную функциональность. Если вы пишете кроссплатформенную программу, вам придётся сделать уровень абстракции над системно-зависимыми библиотеками, и работать с ним в основной программе. Удачи!

Ответ 2



Для этого можно попробовать использовать TurboVision

воскресенье, 29 декабря 2019 г.

Сокрытие ввода в консоли Python 3

#python #console #python_3x


Здравия.
Мне требуется скрывать вводимые в консоль символы (ввод пароля).
Подскажите, это вообще можно сделать?    


Ответы

Ответ 1



import getpass pw = getpass.getpass()

вторник, 24 декабря 2019 г.

Что означает четвёртая колонка в выводе команды «ls -l»?

#windows #bash #console


Что означает набор цифр (выделил цветом). 
Данные появляются после команды ls -al



И как сказать командной строке, чтобы появилась "шапка" на выводимыми данными?
    


Ответы

Ответ 1



Это gid - id группы. Видимо группы не существует. Вы можете убедиться в этом в /etc/group. Либо добавить её туда. Либо сменить группу пользователю, но уже созданные им файлы сохранят id старой группы. Команда id покажет Вам текущую основную группу пользователя и список дополнительных.

понедельник, 16 декабря 2019 г.

Как заблокировать вызовы JS из Console?

#javascript #console


Насмотревшись на Facebok, решил блокировать вызов JS функций из консоли:



На данный момент я вывожу заглушку об использовании консоли и переопределил: 

 console = new Object();


Тем самым заблокировал использования любых log-ов.

Вопрос состоит в следующем:
Можно ли как то отслеживать ввод команд в консоль, либо заблокировать совсем?
    


Ответы

Ответ 1



Ранее это было возможно только в обозревателях сети, основанных на Chrome. Но сейчас разработчики Chrome эту возможность отключили. Об этом сообщил инженер по безопасности в Facebook (на английском). В своём ответе он вкратце описал как он это делал. Также один из пользователей сообщил там о том как это было ранее сделано на Facebook (на английском). Подробное описание. Тем не менее существует возможность просто напугать пользователя, выводя цветные записи в console. К примеру так: console.log('%cОстановитесь!\nВыполнив действия в console ваша учётная запись окажется в чёрном списке!', 'color:#f00;font:bold 26px "Courier New";background-color:#000;padding:16px;padding:50px 500px');

воскресенье, 15 декабря 2019 г.

Не могу вывести UTF символ используя вывод в ncurses

#cpp #linux #c #console #ncurses


Данный кусок кода рисует змейку по координатам, используя функцию mvprintw. Не могу
разобраться как вывести на экран символ - ߜ. Вот код программы:

for(int i = 0; i < length; i++)
{
    x = c[i].X;
    y = c[i].Y;
    unsigned wchar_t head;
    switch(d)
    {
    case UP: head = 'A'; break;


    case DOWN: head = L'ߜ'; break; //ߜ
    // Вот этот символ ^


    case LEFT: head = '<'; break;
    case RIGHT: head = '>'; break;
    default: break;
    }
    mvprintw(food.Y, food.X, "%lc", '$');
    //mvprintw(i, 0, "%d %d\n",y,x);
    mvprintw(y, x, "%c", (i) ? '@' : head);
}

    


Ответы

Ответ 1



Попробуйте, работает у вас или нет. #include #include #include int main (int ac, char *av[]) { char *loc = setlocale(LC_ALL, ""); if (av[1]) puts(loc); wchar_t wc = L'я'; wprintf(L"-- %lc --\n", wc); // wc = 'ߜ' wc = L'ߜ'; wprintf(L"-- %lc --\n", wc); // 'ߜ' } У меня avp@avp-ubu1:hashcode$ uname -a Linux avp-ubu1 4.4.0-72-generic #93-Ubuntu SMP Fri Mar 31 14:07:41 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux avp@avp-ubu1:hashcode$ gcc --version gcc.real (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609 Copyright (C) 2015 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. avp@avp-ubu1:hashcode$ gcc twc.c && ./a.out -- я -- -- ߜ -- avp@avp-ubu1:hashcode$ ./a.out hashsj en_US.UTF-8 avp@avp-ubu1:hashcode$ Обратите внимание, что обычный вывод (puts/printf и т.п.) несовместим с выводом wide символов (wprintf и т.п.). Возможно у вас где-то тестовая печать до вывода wchar_t и поэтому ничего не отображается.

Ответ 2



Обратите внимание : mvprintw(y, x, "%c", (i) ? '@' : head); Вы пытаетесь переменную типа wchar_t вывести по символу форматирования %c. В руководстве по printf написано: %c If no l modifier is present, the int argument is converted to an unsigned char, and the resulting character is written. If an l modifier is present, the wint_t (wide character) argument is converted to a multibyte sequence by a call to the wcrtomb(3) function, with a conversion state starting in the initial state, and the resulting multibyte string is written. Т.е., попробуйте использовать %lc.